Eu tenho uma tabela do InnoDB 'idtimes' (MySQL 5.0.22-log) com colunas
`id` int(11) NOT NULL,
`time` int(20) NOT NULL, [...]
com uma chave única composta
UNIQUE KEY `id_time` (`id`,`time`)
portanto, pode haver vários registros de data e hora por ID e vários IDs por registro de data e hora.
Estou tentando configurar uma consulta na qual obtenho todas as entradas e o próximo maior tempo para cada entrada, se existir, portanto, ele deve retornar, por exemplo:
+-----+------------+------------+
| id | time | nexttime |
+-----+------------+------------+
| 155 | 1300000000 | 1311111111 |
| 155 | 1311111111 | 1322222222 |
| 155 | 1322222222 | NULL |
| 156 | 1312345678 | 1318765432 |
| 156 | 1318765432 | NULL |
+-----+------------+------------+
Agora eu estou tão longe:
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;
mas é claro que isso retorna todas as linhas com r.time> l.time e não apenas o primeiro ...
Acho que vou precisar de uma subseleção como
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;
mas não sei como me referir ao horário atual (sei que o acima não é SQL válido).
Como faço isso com uma única consulta (e eu preferiria não usar @ variáveis que dependem de percorrer a tabela uma linha por vez e lembrar o último valor)?
is null
e a junção ao i3 porwhere not exists (select 1 from itimes i3 where [same clause])
, o código refletiria mais de perto o que queremos expressar.Antes de apresentar a solução, devo observar que não é bonito. Seria muito mais fácil se você tivesse alguma
AUTO_INCREMENT
coluna na sua mesa (não é?)Explicação:
(id, time)
combinações (que também são conhecidas por serem únicas).(l.id, l.time)
, obtenha o primeiror.time
maior quel.time
. Isso acontece com a primeira ordem dor.time
s viaGROUP_CONCAT(r.time ORDER BY r.time)
, o fatiamento do primeiro token viaSUBSTRING_INDEX
.Boa sorte e não espere um bom desempenho se esta tabela for grande.
fonte
Você também pode obter o que deseja de um
min()
eGROUP BY
sem seleção interna:Eu quase apostaria uma grande quantia em dinheiro que o otimizador transforma isso na mesma coisa que a resposta de Erwin Smout de qualquer maneira, e é discutível se é mais claro, mas existe a perfeição ...
fonte