mysql - lentas - consultas sql
Seleccione los 3 registros más recientes donde los valores de una columna son distintos (8)
Esto también:
SELECT * FROM
OrigTable T INNER JOIN
(
SELECT otheridentifier,max(time) AS duration
FROM T
GROUP BY otheridentifier) S
ON S.duration = T.time AND S.otheridentifier = T.otheridentifier.
Tengo la siguiente tabla:
id time text otheridentifier
-------------------------------------------
1 6 apple 4
2 7 orange 4
3 8 banana 3
4 9 pear 3
5 10 grape 2
Lo que quiero hacer es seleccionar los 3 registros más recientes (por tiempo desc), cuyos otheridentifier
s son distintos. Entonces, en este caso, el resultado sería id
''s: 5, 4 y 2.
id
= 3 se omitirá porque hay un registro más reciente con el mismo campo de otheridentifier
.
Esto es lo que traté de hacer:
SELECT * FROM `table` GROUP BY (`otheridentifier`) ORDER BY `time` DESC LIMIT 3
Sin embargo, termino obteniendo filas de id
= 5, 3 y 1 en lugar de 5, 4, 2 como se esperaba.
¿Puede alguien decirme por qué esta consulta no me devolvió lo que esperaba? Traté de cambiar el ORDER BY a ASC, pero esto simplemente reorganiza las filas devueltas a 1, 3, 5.
No devuelve lo que esperaba porque la agrupación ocurre antes de ordenar, como se refleja en la posición de las cláusulas en la declaración de SQL. Desgraciadamente, tendrás que ser más elegante para obtener las filas que deseas. Prueba esto:
SELECT *
FROM `table`
WHERE `id` = (
SELECT `id`
FROM `table` as `alt`
WHERE `alt`.`otheridentifier` = `table`.`otheridentifier`
ORDER BY `time` DESC
LIMIT 1
)
ORDER BY `time` DESC
LIMIT 3
Puede unirse a la tabla en sí mismo para filtrar la última entrada por otro otheridentifier
, y luego tomar las 3 primeras filas de eso:
SELECT last.*
FROM `table` last
LEFT JOIN `table` prev
ON prev.`otheridentifier` = last.`otheridentifier`
AND prev.`time` < last.`time`
WHERE prev.`id` is null
ORDER BY last.`time` DESC
LIMIT 3
Puede usar esta consulta para obtener la respuesta correcta:
SELECT * FROM
(SELECT * FROM `table` order by time DESC)
t group by otheridentifier
Tenía un requisito similar, pero tenía criterios de selección más avanzados. Usando algunas de las otras respuestas, no pude obtener exactamente lo que necesitaba, pero encontré que aún puedes hacer un GROUP BY después y ORDER BY así:
SELECT t.* FROM (SELECT * FROM table ORDER BY time DESC) t
GROUP BY t.otheridentifier
qué pasa
SELECT *, max(time) FROM `table` group by otheridentifier
La respuesta de Andomar es probablemente la mejor, ya que no utiliza una subconsulta.
Un enfoque alternativo:
select *
from `table` t1
where t1.`time` in (
select max(s2.`time`)
from `table` t2
group by t2.otheridentifier
)
SELECT * FROM table t1
WHERE t1.time =
(SELECT MAX(time) FROM table t2
WHERE t2.otheridentifier = t1.otheridentifier)