Maison > base de données > tutoriel mysql > le corps du texte

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

黄舟
Libérer: 2018-05-15 14:14:58
original
3357 Les gens l'ont consulté

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`)
);
Copier après la connexion

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';
Copier après la connexion

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 |
+----+------+---------------+---------------------+
Copier après la connexion

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;
Copier après la connexion
+------+---------------------+
| 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 |
+------+---------------------+
Copier après la connexion

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;
-- 错误写法
Copier après la connexion

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/>
Copier après la connexion

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);
Copier après la connexion

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);
Copier après la connexion

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 |
+----+--------------------+-------+------+---------------+------+---------+------+------+-------------+
Copier après la connexion

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           |
+----+--------------------+-------+------+---------------+------+---------+------------+------+-------------+
Copier après la connexion

É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;
Copier après la connexion

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 |
+------+---------------+---------------------+
Copier après la connexion

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!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal