Maison >base de données >tutoriel mysql >MySQL - Regroupement GROUP BY pour obtenir la valeur maximale des détails du code de l'exemple de champ

MySQL - Regroupement GROUP BY pour obtenir la valeur maximale des détails du code de l'exemple de champ

黄舟
黄舟original
2018-05-15 14:14:583372parcourir

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 :

+----+------+---------------+---------------------+
| 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 :

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 :

-- 错误写法
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
(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
Méthode d'écriture 1
. Ecrire une sous-requête :

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
Ou changer la méthode d'écriture :

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é
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.
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é
5.5.50 :

+----+--------------------+-------+------+---------------+------+---------+------+------+-------------+
| 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 :

+----+--------------------+-------+------+---------------+------+---------+------------+------+-------------+
| 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
Les performances seront meilleures si vous la modifiez directement pour rejoindre :

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 :

+------+---------------+---------------------+
| 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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn