У меня есть InnoDB таблицы «idtimes» (MySQL 5.0.22-log) со столбцами
`id` int(11) NOT NULL,
`time` int(20) NOT NULL, [...]
с составным уникальным ключом
UNIQUE KEY `id_time` (`id`,`time`)
поэтому может быть несколько временных меток на один идентификатор и несколько идентификаторов на одну временную метку.
Я пытаюсь настроить запрос, в котором я получаю все записи плюс следующее большее время для каждой записи, если она существует, поэтому она должна возвращать, например:
+-----+------------+------------+
| id | time | nexttime |
+-----+------------+------------+
| 155 | 1300000000 | 1311111111 |
| 155 | 1311111111 | 1322222222 |
| 155 | 1322222222 | NULL |
| 156 | 1312345678 | 1318765432 |
| 156 | 1318765432 | NULL |
+-----+------------+------------+
Прямо сейчас я так далеко
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;
но, конечно, это возвращает все строки с r.time> l.time, а не только первую ...
Я думаю, мне понадобится подобрать
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;
но я не знаю, как ссылаться на текущее время (я знаю, что выше не является допустимым SQL).
Как мне сделать это с одним запросом (и я бы предпочел не использовать @variables, которые зависят от перехода по таблице по одной строке за раз и запоминания последнего значения)?
is null
заменим i3 и join на i3where not exists (select 1 from itimes i3 where [same clause])
, то код будет более точно отражать то, что мы хотим выразить.Прежде чем представить решение, я должен отметить, что это не красиво. Было бы намного проще, если бы у вас
AUTO_INCREMENT
на столе была какая-то колонка (правда?)Объяснение:
(id, time)
комбинации (которые также известны как уникальные).(l.id, l.time)
получите первое,r.time
которое больше чемl.time
. Это происходит при первом заказеr.time
s viaGROUP_CONCAT(r.time ORDER BY r.time)
, путем разрезания первого токена viaSUBSTRING_INDEX
.Удачи, и не ожидайте хорошей производительности, если этот стол большой.
источник
Вы также можете получить то, что вы хотите от
min()
иGROUP BY
без внутреннего выбора:Я бы почти ставка большой суммы денег , которую Оптимизатор превращает это в одно и то же , как ответ Эрвин Смает в любом случае, и это спорно , является ли это яснее, но там для полноты ...
источник