2011-12-30 7 views
13

Aquí está mi consultafin MySQL con la unión a trabajar

(SELECT * FROM `jokes` WHERE `flags` < 5 AND (`title` LIKE "%only three doors%" OR `joke` LIKE "%only three doors%") ORDER BY `ups` DESC,`downs` ASC) 
UNION 
(SELECT * FROM `jokes` WHERE `flags` < 5 AND (`title` LIKE "%only%" OR `joke` LIKE "%only%") ORDER BY `ups` DESC,`downs` ASC) 
UNION 
(SELECT * FROM `jokes` WHERE `flags` < 5 AND (`title` LIKE "%three%" OR `joke` LIKE "%three%") ORDER BY `ups` DESC,`downs` ASC) 
UNION 
(SELECT * FROM `jokes` WHERE `flags` < 5 AND (`title` LIKE "%doors%" OR `joke` LIKE "%doors%") ORDER BY `ups` DESC,`downs` ASC) 
LIMIT 0, 30 

Por alguna razón, no parece a la orden por altibajos ... que sólo me tira hacia atrás en los resultados el orden en que están naturalmente en la base de datos.

Cuando lo reduzco a una sola consulta, funciona bien, pero aparte de eso, parece ignorarlo.

Asimismo, no quiero pedir por la totalidad de los resultados, o me habría puesto LIMIT 0,30 Order By blah

Respuesta

20

Desde MySQL documentation:

... uso de ORDER BY para las sentencias SELECT individuales implica nada sobre el orden en que aparecen las filas en el resultado final porque UNION de forma predeterminada produce un conjunto de filas desordenado.

Básicamente, la única vez que un ORDER en una unión serán de utilidad es si está utilizando LIMIT también.

Así que si la consulta era así:

(SELECT * FROM `jokes` WHERE `flags` < 5 AND (`title` LIKE "%only three doors%" OR `joke` LIKE "%only three doors%") ORDER BY `ups` DESC,`downs` ASC LIMIT 10) 
UNION ... 

allí tendría que ver los primeros diez registros que se devolverían basado en ese orden, pero no sería necesariamente muestran en orden.

ACTUALIZACIÓN:

probar este -

(SELECT *, 1 as ob FROM `jokes` WHERE `flags` < 5 AND (`title` LIKE "%only three doors%" OR `joke` LIKE "%only three doors%")) 
UNION 
(SELECT *, 2 as ob FROM `jokes` WHERE `flags` < 5 AND (`title` LIKE "%only%" OR `joke` LIKE "%only%")) 
UNION 
(SELECT *, 3 as ob FROM `jokes` WHERE `flags` < 5 AND (`title` LIKE "%three%" OR `joke` LIKE "%three%")) 
UNION 
(SELECT *, 4 as ob FROM `jokes` WHERE `flags` < 5 AND (`title` LIKE "%doors%" OR `joke` LIKE "%doors%")) 
ORDER BY `ob`, `ups` DESC,`downs` ASC LIMIT 0, 30 
+0

¿Tiene alguna idea sobre cómo hacer que funcione como a mí me gustaría? Básicamente, quiero combinar las diferentes consultas, y hacer que cada una de ellas se ordene individualmente por altibajos, y luego combinarlas, una tras otra. –

+0

Así que la primera consulta se ordenó, luego la segunda ordenó. Si el primero es mayor que 30, entonces solo mostraría los primeros 30 en la primera consulta. –

+0

Bleh, esa es una pregunta difícil. ¿Estás diciendo que no quieres ordenar todo el conjunto correctamente?¿Simplemente agrega un conjunto ordenado al final de otro y toma los primeros 30? –

2

Lo que hace la consulta, es ordenar cada sub-consulta por separado y la unificación de todos ellos. No hay garantía de que se ordene el resultado.

lo que hay que hacer es pedir la consulta unificado como tal:

Select * from (
    (SELECT *, 1 as `p` FROM `jokes` WHERE `flags` < 5 AND (`title` LIKE "%only three doors%" OR `joke` LIKE "%only three doors%")) 
    UNION 
    (SELECT *, 2 as `p` FROM `jokes` WHERE `flags` < 5 AND (`title` LIKE "%only%" OR `joke` LIKE "%only%")) 
    UNION 
    (SELECT *, 3 as `p` FROM `jokes` WHERE `flags` < 5 AND (`title` LIKE "%three%" OR `joke` LIKE "%three%")) 
    UNION 
    (SELECT *, 4 as `p` FROM `jokes` WHERE `flags` < 5 AND (`title` LIKE "%doors%" OR `joke` LIKE "%doors%")) 
    ) ORDER BY `p` ASC, `ups` DESC,`downs` ASC 
+0

Había pensado en eso, pero como mencioné anteriormente, ese no es el resultado que estoy buscando. Todos los resultados de la primera consulta siempre deben venir antes que los de la segunda. –

+1

He editado la consulta para que se ajuste a tus necesidades (se ha agregado un campo adicional 'p') –

+1

Te la daría, pero el otro tipo tenía la solución correcta primero. Gracias a –

0

Usted debe ser capaz de utilizar UNION ALL para eliminar eliminación de duplicados (y también conjunto de clasificación de resultados completo). Usando eso, el conjunto de resultados debe estar en el orden de las declaraciones seleccionadas en la consulta.

+0

Así que simplemente reemplace UNION con UNION ALL? –

+0

Pruébalo, mira si ayuda, si no, no desperdicié más de 20 segundos de tu tiempo :) ... (no tengo un mysql local a mano para probarlo, pero debería marcar la diferencia) – cairnz

+0

espera No quiero duplicados. –

3

me dieron solución para esto:

SELECT * 
FROM (
    (SELECT 1 as SortRank, uid, title, state, zip, region,cantone FROM company WHERE city=".$city." AND region=".$region." AND cantone=".$cantone.") 
    UNION 
    (SELECT 2 as SortRank, uid, title, state, zip, region,cantone FROM company WHERE region=".$region." AND cantone=".$cantone.") 
    union all 
    (SELECT 3 as SortRank, uid, title, state, zip, region,cantone FROM company WHERE cantone=".$cantone.") 
) As u 
GROUP BY uid 
ORDER BY SortRank,state=2, title ASC 
LIMIT 0,10 

En consulta anterior quiero dar como resultado, por ejemplo. primero muestre todos los registros con ciudad, región y cantón, si la ciudad no está disponible, muestre todos los registros con región y cantón y luego todos los registros con cantón de ciudad. Por lo tanto, al eliminar registros repetitivos utilicé la cláusula GROUP BY, ordenará todos los registros basados ​​en el grupo de consulta y luego todos los registros con state = 2.

+0

¡Gracias! Estuve pasando horas tratando de resolver esto. –

Cuestiones relacionadas