Tengo una tabla InnoDB 'idtimes' (MySQL 5.0.22-log) con columnas
`id` int(11) NOT NULL,
`time` int(20) NOT NULL, [...]
con una clave compuesta única
UNIQUE KEY `id_time` (`id`,`time`)
por lo que puede haber múltiples marcas de tiempo por ID y múltiples ID por marca de tiempo.
Estoy tratando de configurar una consulta donde obtengo todas las entradas más el siguiente tiempo mayor para cada entrada, si existe, por lo que debería devolver, por ejemplo:
+-----+------------+------------+
| id | time | nexttime |
+-----+------------+------------+
| 155 | 1300000000 | 1311111111 |
| 155 | 1311111111 | 1322222222 |
| 155 | 1322222222 | NULL |
| 156 | 1312345678 | 1318765432 |
| 156 | 1318765432 | NULL |
+-----+------------+------------+
En este momento estoy tan lejos:
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;
pero, por supuesto, esto devuelve todas las filas con r.time> l.time y no solo la primera ...
Creo que necesitaré una subselección 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;
pero no sé cómo referirme a la hora actual (sé que lo anterior no es SQL válido).
¿Cómo hago esto con una sola consulta (y preferiría no usar @variables que dependen de recorrer la tabla una fila a la vez y recordar el último valor)?
is null
y unimos a i3 conwhere not exists (select 1 from itimes i3 where [same clause])
, entonces el código reflejaría más de cerca lo que queremos expresar.Antes de presentar la solución, debo señalar que no es bonita. Sería mucho más fácil si tuviera alguna
AUTO_INCREMENT
columna en su tabla (¿verdad?)Explicación:
(id, time)
combinaciones (que también se sabe que son únicas).(l.id, l.time)
, obtenga el primero,r.time
que es mayor quel.time
. Esto sucede con el primer pedido de lar.time
víaGROUP_CONCAT(r.time ORDER BY r.time)
, cortando el primer token víaSUBSTRING_INDEX
.Buena suerte y no esperes un buen rendimiento si esta tabla es grande.
fuente
También se puede conseguir lo que quiere de una
min()
yGROUP BY
sin la SELECT interna:Yo casi apuesto a una gran suma de dinero que el optimizador convierte esto en lo mismo que la respuesta de Erwin Smout de todos modos, y es discutible si es más claro, pero no lo es para redondear ...
fuente