J'ai une table InnoDB 'idtimes' (MySQL 5.0.22-log) avec des colonnes
`id` int(11) NOT NULL,
`time` int(20) NOT NULL, [...]
avec une clé unique composée
UNIQUE KEY `id_time` (`id`,`time`)
il peut donc y avoir plusieurs horodatages par identifiant et plusieurs identifiants par horodatage.
J'essaye de mettre en place une requête où j'obtiens toutes les entrées plus la prochaine fois plus grande pour chaque entrée, si elle existe, donc elle devrait retourner par exemple:
+-----+------------+------------+
| id | time | nexttime |
+-----+------------+------------+
| 155 | 1300000000 | 1311111111 |
| 155 | 1311111111 | 1322222222 |
| 155 | 1322222222 | NULL |
| 156 | 1312345678 | 1318765432 |
| 156 | 1318765432 | NULL |
+-----+------------+------------+
En ce moment je suis si loin:
SELECT l.id, l.time, r.time FROM
idtimes AS l LEFT JOIN idtimes AS r ON l.id = r.id
WHERE l.time < r.time ORDER BY l.id ASC, l.time ASC;
mais bien sûr, cela renvoie toutes les lignes avec r.time> l.time et pas seulement la première ...
Je suppose que j'aurai besoin d'une sous-sélection comme
SELECT outer.id, outer.time,
(SELECT time FROM idtimes WHERE id = outer.id AND time > outer.time
ORDER BY time ASC LIMIT 1)
FROM idtimes AS outer ORDER BY outer.id ASC, outer.time ASC;
mais je ne sais pas comment me référer à l'heure actuelle (je sais que ce qui précède n'est pas du SQL valide).
Comment puis-je faire cela avec une seule requête (et je préférerais ne pas utiliser des variables @ qui dépendent de la progression dans le tableau une ligne à la fois et de la mémorisation de la dernière valeur)?
is null
et la jointure avec i3where not exists (select 1 from itimes i3 where [same clause])
, le code refléterait plus précisément ce que nous voulons exprimer.Avant de présenter la solution, je dois noter qu'elle n'est pas jolie. Ce serait beaucoup plus facile si vous aviez une
AUTO_INCREMENT
colonne sur votre table (pensez-vous?)Explication:
(id, time)
combinaisons (qui sont également connues pour être uniques).(l.id, l.time)
, obtenez le premierr.time
qui est supérieur àl.time
. Cela se produit lors de la première commande dur.time
s viaGROUP_CONCAT(r.time ORDER BY r.time)
, en coupant le premier jeton viaSUBSTRING_INDEX
.Bonne chance et ne vous attendez pas à de bonnes performances si ce tableau est volumineux.
la source
Vous pouvez également obtenir ce que vous voulez d'un
min()
etGROUP BY
sans sélection interne:Je parierais presque une grosse somme d'argent que l'optimiseur transforme cela en la même chose que la réponse d'Erwin Smout de toute façon, et on peut se demander si c'est plus clair, mais là c'est pour être complet ...
la source