MySQL - GROUP BY regroupant les détails d'un exemple de code pour obtenir la valeur maximale du champ :
Supposons qu'il existe un scénario commercial dans lequel les informations d'enregistrement de connexion de l'utilisateur doivent être interrogées et la structure de la table est la suivante :
CREATE TABLE `tb` ( `id` int(11) NOT NULL AUTO_INCREMENT, `uid` int(11) NOT NULL, `ip` varchar(16) NOT NULL, `login_time` datetime, PRIMARY KEY (`id`), KEY (`uid`) );
Obtenons quelques données de test supplémentaires :
INSERT INTO tb SELECT null, 1001, '192.168.1.1', '2017-01-21 16:30:47'; INSERT INTO tb SELECT null, 1003, '192.168.1.153', '2017-01-21 19:30:51'; INSERT INTO tb SELECT null, 1001, '192.168.1.61', '2017-01-21 16:50:41'; INSERT INTO tb SELECT null, 1002, '192.168.1.31', '2017-01-21 18:30:21'; INSERT INTO tb SELECT null, 1002, '192.168.1.66', '2017-01-21 19:12:32'; INSERT INTO tb SELECT null, 1001, '192.168.1.81', '2017-01-21 19:53:09'; INSERT INTO tb SELECT null, 1001, '192.168.1.231', '2017-01-21 19:55:34';
Données du tableau : <br/>
+----+------+---------------+---------------------+ | id | uid | ip | login_time | +----+------+---------------+---------------------+ | 1 | 1001 | 192.168.1.1 | 2017-01-21 16:30:47 | | 2 | 1003 | 192.168.1.153 | 2017-01-21 19:30:51 | | 3 | 1001 | 192.168.1.61 | 2017-01-21 16:50:41 | | 4 | 1002 | 192.168.1.31 | 2017-01-21 18:30:21 | | 5 | 1002 | 192.168.1.66 | 2017-01-21 19:12:32 | | 6 | 1001 | 192.168.1.81 | 2017-01-21 19:53:09 | | 7 | 1001 | 192.168.1.231 | 2017-01-21 19:55:34 | +----+------+---------------+---------------------+
Si vous avez seulement besoin de trouver l'heure de la dernière connexion d'un utilisateur, vous pouvez simplement écrire : <br/>
SELECT uid, max(login_time) FROM tb GROUP BY uid;
+------+---------------------+ | uid | max(login_time) | +------+---------------------+ | 1001 | 2017-01-21 19:55:34 | | 1002 | 2017-01-21 19:12:32 | | 1003 | 2017-01-21 19:30:51 | +------+---------------------+
Si vous devez également interroger d'autres informations sur la dernière connexion de l'utilisateur, vous ne pouvez pas utiliser ce SQL pour écrire : <br/>
-- 错误写法 SELECT uid, ip, max(login_time) FROM tb GROUP BY uid; -- 错误写法
Une telle instruction n'est pas un standard SQL Bien qu'elle puisse être exécutée avec succès dans la base de données MySQL, la valeur renvoyée est inconnue <br/> (Si sql_mode est activé only_full_group_by, elle est activée. ne sera pas exécuté avec succès.)
<br/>
Peut-être que le champ ip prendra la valeur de la première ligne avant le groupe uid, ce qui n'est évidemment pas l'information requise <br/>Méthode d'écriture 1<br/>. Ecrire une sous-requête : <br/>
SELECT a.uid, a.ip, a.login_time FROM tb a WHERE a.login_time in ( SELECT max(login_time) FROM tb GROUP BY uid);
Méthode d'écriture 2<br/> Ou changer la méthode d'écriture : <br/>
SELECT a.uid, a.ip, a.login_time FROM tb a WHERE a.login_time = ( SELECT max(login_time) FROM tb WHERE a.uid = uid);
D'ailleurs, je l'ai testé <br/> Dans les versions antérieures à 5.6, la méthode d'écriture ②Ce SQL est exécuté lorsque la quantité de données est importante et que les performances visuelles sont médiocres. <br/>Dans les versions 5.6 et supérieures, l'écriture ② de ce sql sera beaucoup plus rapide, et le plan d'exécution a également changé <br/>5.5.50 : <br/>
+----+--------------------+-------+------+---------------+------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+--------------------+-------+------+---------------+------+---------+------+------+-------------+ | 1 | PRIMARY | a | ALL | NULL | NULL | NULL | NULL | 7 | Using where | | 2 | DEPENDENT SUBQUERY | tb | ALL | uid | NULL | NULL | NULL | 7 | Using where | +----+--------------------+-------+------+---------------+------+---------+------+------+-------------+
5.6.30 : <br/>
+----+--------------------+-------+------+---------------+------+---------+------------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+--------------------+-------+------+---------------+------+---------+------------+------+-------------+ | 1 | PRIMARY | a | ALL | NULL | NULL | NULL | NULL | 7 | Using where | | 2 | DEPENDENT SUBQUERY | tb | ref | uid | uid | 4 | test.a.uid | 1 | NULL | +----+--------------------+-------+------+---------------+------+---------+------------+------+-------------+
Écriture 3<br/>Les performances seront meilleures si vous la modifiez directement pour rejoindre :<br/>
SELECT a.uid, a.ip, a.login_time FROM (SELECT uid, max(login_time) login_time FROM tb GROUP BY uid ) b JOIN tb a ON a.uid = b.uid AND a.login_time = b.login_time;
Bien sûr, les résultats sont les mêmes :<br/>
+------+---------------+---------------------+ | uid | ip | login_time | +------+---------------+---------------------+ | 1003 | 192.168.1.153 | 2017-01-21 19:30:51 | | 1002 | 192.168.1.66 | 2017-01-21 19:12:32 | | 1001 | 192.168.1.231 | 2017-01-21 19:55:34 | +------+---------------+---------------------+
Remarque : Si vous souhaitez regrouper la valeur minimale, modifiez simplement la fonction et le symbole correspondants.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!