Seleccione una fila y filas a su alnetworkingedor

Ok, digamos que tengo una table con fotos.

Lo que quiero hacer es mostrar en una página la foto basada en la identificación en el URI. Debajo de la foto, quiero tener 10 miniaturas de fotos cercanas y la foto actual debe estar en el centro de las miniaturas.

Aquí está mi consulta hasta ahora (esto es solo un ejemplo, utilicé 7 como id):

SELECT A.* FROM (SELECT * FROM media WHERE id < 7 ORDER BY id DESC LIMIT 0, 4 UNION SELECT * FROM media WHERE id >= 7 ORDER BY id ASC LIMIT 0, 6 ) as A ORDER BY A.id 

Pero me sale este error:

 #1221 - Incorrect usage of UNION and ORDER BY 

Solo se puede definir una cláusula ORDER BY para una consulta de UNION . No importa si usa UNION o UNION ALL . MySQL admite la cláusula LIMIT en partes de una consulta de UNION , pero es relativamente inútil sin la capacidad de definir el order.

MySQL también carece de funciones de sorting, que necesita para hacer frente a lagunas en los datos (faltantes debido a la eliminación de inputs). La única alternativa es usar una variable incremental en la instrucción SELECT:

 SELECT t.id, @rownum := @rownum+1 as rownum FROM MEDIA t, (SELECT @rownum := 0) r 

Ahora podemos get una list numerada consecutivamente de las filas, para que podamos usar:

 WHERE rownum BETWEEN @midpoint - ROUND(@midpoint/2) AND @midpoint - ROUND(@midpoint/2) +@upperlimit 

Usando 7 como el valor para @midpoint, @midpoint - ROUND(@midpoint/2) devuelve un valor de 4 . Para get 10 filas en total, establezca el valor @upperlimit en 10. Aquí está la consulta completa:

 SELECT x.* FROM (SELECT t.id, @rownum := @rownum+1 as rownum FROM MEDIA t, (SELECT @rownum := 0) r) x WHERE x.rownum BETWEEN @midpoint - ROUND(@midpoint/2) AND @midpoint - ROUND(@midpoint/2) + @upperlimit 

Pero si aún desea usar LIMIT , puede usar:

  SELECT x.* FROM (SELECT t.id, @rownum := @rownum+1 as rownum FROM MEDIA t, (SELECT @rownum := 0) r) x WHERE x.rownum >= @midpoint - ROUND(@midpoint/2) ORDER BY x.id ASC LIMIT 10 

Resuelvo esto usando el siguiente código:

 SELECT A.* FROM ( ( SELECT * FROM gossips WHERE id < 7 ORDER BY id DESC LIMIT 2 ) UNION ( SELECT * FROM gossips WHERE id > 7 ORDER BY id ASC LIMIT 2 ) ) as A ORDER BY A.id 

No creo que pueda tener un "pedido por" en diferentes secciones de UNIÓN. Podrías hacer algo como esto:

 SELECT * FROM media where id >= 7 - 4 and id <= 7 + 4 ORDER BY id 

Estoy de acuerdo con la respuesta sugerida por malonso (+1), pero si la testing con id = 1, obtendrá solo 5 miniaturas. No sé si quieres este comportamiento. Si quiere siempre 10 pulgares, puede intentar:

 select top 10 * from media where id > 7 - 4 

El problema es que select top depende de la database (en este caso es una cláusula de server sql). Otra database tiene cláusulas similares:

Oráculo:

 SELECT * media FROM media WHERE ROWNUM < 10 AND id > 7 - 4 

MySQL:

 SELECT * FROM media WHERE id > 7 - 4 LIMIT 10 

Entonces quizás puedas usar el último.

Si lo hacemos, tendremos el mismo problema si quiere los últimos 10 pulgares. Por ejemplo, si tenemos 90 pulgares y damos un id = 88 … Puede resolverlo agregando una condición OR. En MySQL será algo así como:

 SELECT * FROM media WHERE id > 7 - 4 OR (Id+5) > (select COUNT(1) from media) LIMIT 10 

Si está contento de usar tablas temporales, su consulta original podría desglosarse para usarlas.

 SELECT * FROM media WHERE id < 7 ORDER BY id DESC LIMIT 0, 4 INTO TEMP t1; INSERT INTO t1 SELECT * FROM media WHERE id >= 7 ORDER BY id ASC LIMIT 0, 6; select * from t1 order by id; drop table t1; 

Pruebe unir todo en su lugar. Union requiere que el server se asegure de que los resultados sean únicos y esto entra en conflicto con su order.

Tuve que resolver un problema similar, pero necesitaba contar situaciones en las que siempre obtuvimos el mismo número de filas, incluso si la fila deseada estaba cerca de la parte superior o inferior del set de resultados (es decir, no exactamente en el medio).

Esta solución es un ajuste de la respuesta de los Ponies de OMG, pero donde el rownum alcanza su máximo en la fila deseada:

 set @id = 7; SELECT natSorted.id FROM ( SELECT gravitySorted.* FROM ( SELECT Media.id, IF(id <= @id, @gravity := @gravity + 1, @gravity := @gravity - 1) AS gravity FROM Media, (SELECT @gravity := 0) g ) AS gravitySorted ORDER BY gravity DESC LIMIT 10 ) natSorted ORDER BY id; 

Aquí hay un desglose de lo que está sucediendo:

NOTA: en el siguiente ejemplo hice una tabla con 20 filas y eliminé los identificadores 6 y 9 para asegurarme de que un espacio en los identificadores no afecta los resultados.

Primero asignamos a cada fila un valor de gravedad que se centra alnetworkingedor de la fila particular que está buscando (en este caso, donde id es 7). Cuanto más cerca esté la fila de la fila deseada, mayor será el valor:

 SET @id = 7; SELECT Media.id, IF(id <= @id, @gravity := @gravity + 1, @gravity := @gravity - 1) AS gravity FROM Media, (SELECT @gravity := 0) g 

devoluciones:

 +----+---------+ | id | gravity | +----+---------+ | 1 | 1 | | 2 | 2 | | 3 | 3 | | 4 | 4 | | 5 | 5 | | 7 | 6 | | 8 | 5 | | 10 | 4 | | 11 | 3 | | 12 | 2 | | 13 | 1 | | 14 | 0 | | 15 | -1 | | 16 | -2 | | 17 | -3 | | 18 | -4 | | 19 | -5 | | 20 | -6 | | 21 | -7 | +----+---------+ 

A continuación, pedimos todos los resultados por el valor de gravedad y el límite en el número deseado de filas:

 SET @id = 7; SELECT gravitySorted.* FROM ( SELECT Media.id, IF(id <= @id, @gravity := @gravity + 1, @gravity := @gravity - 1) AS gravity FROM Media, (SELECT @gravity := 0) g ) AS gravitySorted ORDER BY gravity DESC LIMIT 10 

devoluciones:

  +----+---------+ | id | gravity | +----+---------+ | 7 | 6 | | 5 | 5 | | 8 | 5 | | 4 | 4 | | 10 | 4 | | 3 | 3 | | 11 | 3 | | 2 | 2 | | 12 | 2 | | 1 | 1 | +----+---------+ 

En este punto tenemos todos los ID deseados, solo tenemos que orderarlos a su order original:

 set @id = 7; SELECT natSorted.id FROM ( SELECT gravitySorted.* FROM ( SELECT Media.id, IF(id <= @id, @gravity := @gravity + 1, @gravity := @gravity - 1) AS gravity FROM Media, (SELECT @gravity := 0) g ) AS gravitySorted ORDER BY gravity DESC LIMIT 10 ) natSorted ORDER BY id; 

devoluciones:

 +----+ | id | +----+ | 1 | | 2 | | 3 | | 4 | | 5 | | 7 | | 8 | | 10 | | 11 | | 12 | +----+