El uso de variables de usuario al número filas
a menudo encontrar respuestas aquí en sugiriendo así que el uso de variables de usuario para numerar alguna cosa o la otra. Quizás el ejemplo más claro sea una consulta para seleccionar cada segunda fila de un conjunto de resultados dado. (Esta pregunta y consulta es similar a this answer, pero fue this la respuesta que en realidad desencadenó esta pregunta aquí).garantías cuando se utilizan variables de usuario al número filas
SELECT *
FROM (SELECT *, (@row := @row + 1) AS rownum
FROM (SELECT @row := 0) AS init, tablename
ORDER BY tablename.ordercol
) sub
WHERE rownum % 2 = 1
Este enfoque parece funcionar normalmente.
razones para tener cuidado
Por otro lado, el MySQ docs Estado:
Como regla general, nunca se debe asignar un valor a una variable de usuario y leer el valor dentro de la misma declaración . Puede obtener los resultados que espera, pero esto no está garantizado. El orden de evaluación para expresiones que involucran variables de usuario no está definido y puede cambiar en función de los elementos contenidos en una declaración dada; Además, no se garantiza que este orden sea el mismo entre versiones del servidor MySQL.
pregunta Core
Así que mi pregunta no es cómo lograr un ordenamiento como el uso de servidores actuales, pero en cambio si la solución que se sugiere el uso de variables de usuario es garantizado para trabajar en todas las circunstancias (razonable) y para todas las versiones futuras de MySQL.
Por "garantías" Me refiero a fuentes autorizadas como la documentación de MySQL o algunas conformidades estándar de MySQL. Al carecer de respuestas autorizadas, otras fuentes como los tutoriales de uso frecuente o partes del código fuente de MySQL podrían citarse en su lugar. Por "works" Me refiero al hecho de que las asignaciones se ejecutarán secuencialmente, una vez por fila del resultado, y en el orden inducido por la línea ORDER BY
.
Ejemplo de consulta de ruptura
Para dar un ejemplo de cómo fácilmente fallan cosas:
SELECT *
FROM (SELECT *, (@row := @row + 1) AS rownum
FROM (SELECT @row := 0) AS init, tablename
HAVING rownum > 0
ORDER BY tablename.ordercol
) sub
WHERE rownum % 2 = 1
producirá un resultado vacío en el MySQL 5.5.27 instalada actualmente en SQL Fiddle. El motivo parece ser que la condición HAVING
hace que la expresión rownum
se evalúe dos veces, por lo que el resultado final solo tendrá números pares. Tengo una idea de lo que está sucediendo detrás de escena, y no estoy afirmando que la consulta con el HAVING
tiene mucho sentido. Solo quiero demostrar que hay una línea fina entre el código que funciona y el código que se ve muy similar pero se rompe.
@hvd, gracias por el [puntero] (http://bugs.mysql.com/bug.php?id=35893) en la solicitud de función 'ROW_NUMBER'. [Dems] (http://stackoverflow.com/users/53341/dems) recientemente [me dijo] (http://stackoverflow.com/a/12727443) acerca de esta función. Parece bastante potente y bien definido para arrancar. Lástima que parece haber poco progreso en esa solicitud desde 2008. – MvG
Eliminé mi comentario cuando vi que 'ROW_NUMBER' ya se mencionó en los comentarios y respuestas a su pregunta anterior :) – hvd
[¿Ya leyó este artículo?] (http://www.xaprb.com/blog/2006/12/15/advanced-mysql-user-variable-techniques/) Particularmente, la parte 'MySQL no evalúa las expresiones que contienen variables de usuario hasta que se envían al cliente, ' –