2008-10-03 25 views
5

http://thedailywtf.com/Articles/The-Hot-Room.aspxMySQL: seleccionar filas condicionalmente siguiente y anterior

Ves como en la parte inferior hay enlaces a los artículos siguientes y anteriores ("sin preparación para Divide_By_Zero" y "un juego completamente diferente")? ¿Cómo hago eso, pero seleccionando los artículos no privados siguientes y anteriores? Esto funciona para seleccionar el próximo artículo:

SELECT * FROM articles WHERE id > ? AND private IS NULL 

Pero no puedo encontrar la manera de seleccionar el artículo anterior.

¿Cuál es la forma correcta/eficiente de hacer esto, preferiblemente en una consulta?

Respuesta

9

o la ampliación de la respuesta de Jeremy ...
En una consulta

(SELECT * FROM articles WHERE id > ? 
AND private IS NULL 
ORDER BY id ASC LIMIT 1) 
UNION 
(SELECT * FROM articles WHERE id < ? 
AND private IS NULL 
ORDER BY id DESC LIMIT 1) 
+2

Esto se comporta raro cuando estás en el primer/último registro de tu selección. Devuelve solo un registro, pero no puedo encontrar una manera de averiguar cuál. – Fuzzy76

+0

Si el ID del artículo actual es 10 y la consulta solo arroja un resultado, esto es lo que puede hacer: - si el ID es inferior a 10, el artículo es anterior - si el ID es superior a 10, el artículo es más reciente Si todavía no está resolviendo el problema, puede ampliar la consulta y agregar alguna columna significativa, como 'seleccionar 'más nuevo' como cuando, * de artículos ...' –

5

Así es como yo lo haría:

-- next 
SELECT * FROM articles WHERE id > ? AND private IS NULL ORDER BY id ASC LIMIT 1 

-- previous 
SELECT * FROM articles WHERE id < ? AND private IS NULL ORDER BY id DESC LIMIT 1 

No estoy seguro de cómo hacerlo en una consulta. Lo único que se me ocurre es posiblemente obtener tanto el artículo que está mostrando como el artículo siguiente en una consulta, pero eso podría ser demasiado confuso.

2

¿Qué tal un anidado de selección?

SELECT * FROM articles WHERE id IN (
    SELECT id FROM articles WHERE id > ? AND private IS NULL ORDER BY id ASC LIMIT 1) 
) 
OR id IN (
    SELECT id FROM articles WHERE id < ? AND private IS NULL ORDER BY id DESC LIMIT 1 
); 
2

Puede salirse con subselects etc en su caso en particular, pero si necesitas algo más complicado (por ejemplo: dado un saldo inicial y una lista de pagos y devoluciones de cargo, el cálculo de saldo de la cuenta en cada punto de tiempo) es probable que desee escribir un procedimiento almacenado que utilice cláusulas SQL REPEAT/WHILE/LOOP y permita el uso de variables, etc.

Cuestiones relacionadas