Hay una tabla de routes que contiene datos como se muestra a continuación:
Id GroupID TickID Data ------------------------- 1 1 1 A 2 1 2 B 3 1 3 C 4 2 1 D 5 2 2 E 6 3 1 FTengo un archivo PHP donde el usuario debería poder pasar un "TickID", y luego el script debería devolver: para cada GroupID, los datos para el TickID dado por el usuario, pero si el usuario pasa un TickID que es más grande que el TickID máximo en un ID de grupo determinado, debe devolverse la ÚLTIMA fila para ese ID de grupo en particular.
es decir
UserInput, TickID 1, devuelve
Id GroupID TickID Data ------------------------- 1 1 1 A 4 2 1 D 6 3 1 FUserInput, TickID 3, devuelve
Id GroupID TickID Data ------------------------- 3 1 3 C 5 2 2 E 6 3 1 FEncontré cómo seleccionar la fila "más reciente", es decir, el TickID más grande por GroupID con un buen rendimiento ya aquí: Recuperación del último registro en cada grupo - MySQL
Pero no estoy seguro de cómo combinarlo con una selección de filas intermedias.
EDITAR Lo que tengo ahora es: Hacer 3 consultas:
1ra consulta: Seleccione el TickID más grande para cada grupo SELECT GroupID, MAX(TickID) maxTick From routes GROUP BY GroupID
Entonces haga dos consultas: una para los GroupsID que tienen una entrada de TickID en la base de datos más grande que la entrada del usuario -> SELECT GroupID, Data From routes WHERE TickID = userTickID GROUP BY GroupID
Y haga otra consulta para los Grupos que no tienen un TickID tan grande como el proporcionado por el usuario: seleccione los TickID más grandes para esos Grupos. De manera similar a Recuperar el último registro en cada grupo - MySQL
Parece un gran fracaso. ¿Alguna idea para mejorarlo?
Yo expresaría su consulta como:
SELECT r1.* FROM routes r1 INNER JOIN ( SELECT GroupID, MAX(TickID) AS MaxTickID FROM routes GROUP BY GroupID ) r2 ON r1.GroupID = r2.GroupID AND (r1.TickID = userTickID OR (r1.TickID = r2.MaxTickID AND r2.MaxTickID < userTickID)); La lógica aquí es un ligero juego con el enfoque canónico máximo por grupo de unión. Aquí tomamos el TickID que es el máximo en el grupo solo si el ID de tick del usuario es mayor que el máximo. De lo contrario, tomamos el registro cuyo TickID coincide con el valor de entrada del usuario.
Agregar el siguiente índice en routes debería acelerar drásticamente la subconsulta máxima:
CREATE INDEX idx ON routes (GroupID, TickID);Creo que esto depende de los datos.
(A) la consulta es la siguiente.
select * from routes where (GroupID, TickID) in (select GroupID, max(TickID) from routes where TickID<=3 group by GroupID);(B) la consulta es la siguiente.
with MatchUserInput as ( select GroupID, TickID from routes where TickID=3 ), MaxTickID as ( select GroupID, max(TickID) from routes where GroupID not in (select GroupID from MatchUserInput) group by GroupID ) select * from routes where (GroupID, TickID) in ( select * from MatchUserInput union select * from MaxTickID );Reemplace el "3" anterior con UserInput.