Mam tabelę InnoDB „idtimes” (MySQL 5.0.22-log) z kolumnami
`id` int(11) NOT NULL,
`time` int(20) NOT NULL, [...]
ze złożonym unikalnym kluczem
UNIQUE KEY `id_time` (`id`,`time`)
więc może istnieć wiele znaczników czasu na identyfikator i wiele identyfikatorów na znacznik czasu.
Próbuję skonfigurować zapytanie, w którym otrzymuję wszystkie wpisy plus następny większy czas dla każdego wpisu, jeśli taki istnieje, więc powinien zwrócić np .:
+-----+------------+------------+
| id | time | nexttime |
+-----+------------+------------+
| 155 | 1300000000 | 1311111111 |
| 155 | 1311111111 | 1322222222 |
| 155 | 1322222222 | NULL |
| 156 | 1312345678 | 1318765432 |
| 156 | 1318765432 | NULL |
+-----+------------+------------+
W tej chwili jestem do tej pory:
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;
ale oczywiście zwraca wszystkie wiersze z r.time> l.time i nie tylko pierwszy ...
Chyba będę potrzebować podselekcji jak
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;
ale nie wiem, jak odwoływać się do bieżącej godziny (wiem, że powyższe nie jest poprawnym SQL).
Jak to zrobić za pomocą pojedynczego zapytania (i wolałbym nie używać @ zmiennych, które zależą od przejścia przez tabelę jeden wiersz na raz i zapamiętania ostatniej wartości)?
is null
i przyłączenie do i3where not exists (select 1 from itimes i3 where [same clause])
, kod lepiej odzwierciedlałby to, co chcemy wyrazić.Przed przedstawieniem rozwiązania należy zauważyć, że nie jest ładne. Byłoby znacznie łatwiej, gdybyś miał
AUTO_INCREMENT
kolumnę na stole (prawda?)Wyjaśnienie:
(id, time)
kombinacji (które są również znane jako unikalne).(l.id, l.time)
otrzymaj pierwszy,r.time
który jest większy niżl.time
. Dzieje się tak przy pierwszym zamówieniur.time
s poprzezGROUP_CONCAT(r.time ORDER BY r.time)
, poprzez przecięcie pierwszego tokena przezSUBSTRING_INDEX
.Powodzenia i nie oczekuj dobrej wydajności, jeśli ta tabela jest duża.
źródło
Możesz również uzyskać to, czego chcesz od
min()
aGROUP BY
bez wewnętrznego wyboru:Chciałbym prawie postawić dużą sumę pieniędzy, że optymalizator zamienia to w samej rzeczy jako odpowiedź Erwina Smout w każdym razie, i to jest wątpliwe, czy to jakieś jaśniejsze, ale nie jest to dla zasady ...
źródło