Ich habe eine InnoDB-Tabelle 'idtimes' (MySQL 5.0.22-log) mit Spalten
`id` int(11) NOT NULL,
`time` int(20) NOT NULL, [...]
mit einem zusammengesetzten eindeutigen Schlüssel
UNIQUE KEY `id_time` (`id`,`time`)
Es kann also mehrere Zeitstempel pro ID und mehrere IDs pro Zeitstempel geben.
Ich versuche, eine Abfrage einzurichten, bei der ich für jeden Eintrag alle Einträge sowie die nächsthöhere Zeit erhalte, falls vorhanden. Daher sollte diese Abfrage beispielsweise Folgendes zurückgeben:
+-----+------------+------------+
| id | time | nexttime |
+-----+------------+------------+
| 155 | 1300000000 | 1311111111 |
| 155 | 1311111111 | 1322222222 |
| 155 | 1322222222 | NULL |
| 156 | 1312345678 | 1318765432 |
| 156 | 1318765432 | NULL |
+-----+------------+------------+
Im Moment bin ich soweit:
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;
aber das gibt natürlich alle Zeilen mit r.time> l.time zurück und nicht nur die erste ...
Ich denke, ich brauche eine Unterauswahl wie
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;
aber ich weiß nicht, wie ich mich auf die aktuelle Zeit beziehen soll (ich weiß, dass das oben Gesagte kein gültiges SQL ist).
Wie mache ich das mit einer einzelnen Abfrage (und ich würde es vorziehen, keine @ -Variablen zu verwenden, die davon abhängen, zeilenweise durch die Tabelle zu springen und den letzten Wert zu speichern)?
is null
und die Verknüpfung zu i3 durch ersetzenwhere not exists (select 1 from itimes i3 where [same clause])
würden, würde der Code besser das widerspiegeln, was wir ausdrücken möchten.Bevor ich die Lösung vorstelle, sollte ich beachten, dass sie nicht hübsch ist. Es wäre viel einfacher, wenn Sie eine
AUTO_INCREMENT
Spalte auf Ihrem Tisch hätten (oder?)Erläuterung:
(id, time)
Kombinationen erhalten (die auch als eindeutig bekannt sind).(l.id, l.time)
die erste,r.time
die größer ist alsl.time
. Dies geschieht mit der ersten Bestellung desr.time
s viaGROUP_CONCAT(r.time ORDER BY r.time)
, dem ersten Token viaSUBSTRING_INDEX
.Viel Glück und erwarten Sie keine gute Leistung, wenn diese Tabelle groß ist.
quelle
Sie können auch bekommen, was Sie wollen,
min()
undGROUP BY
ohne innere Auswahl:Ich würde fast eine große Summe Geld wetten, dass der Optimierer dies sowieso in das Gleiche wie Erwin Smouts Antwort umwandelt, und es ist fraglich, ob es klarer ist, aber da ist es der Vollständigkeit halber ...
quelle