Foros del Web » Programación para mayores de 30 ;) » Bases de Datos General » Mysql »

UNION ALL no respeta orden de ORDER BY???

Estas en el tema de UNION ALL no respeta orden de ORDER BY??? en el foro de Mysql en Foros del Web. Hola! Tengo dos consultas distintas (difieren en los criterios de búsqueda y orden de resultados) que devuelven los mismos campos, y necesito unir los resultados, ...
  #1 (permalink)  
Antiguo 04/03/2009, 10:30
Avatar de qvixote  
Fecha de Ingreso: marzo-2008
Mensajes: 79
Antigüedad: 16 años, 8 meses
Puntos: 2
UNION ALL no respeta orden de ORDER BY???

Hola!

Tengo dos consultas distintas (difieren en los criterios de búsqueda y orden de resultados) que devuelven los mismos campos, y necesito unir los resultados, una consulta luego de otra. Lo hice de esta forma:

Código PHP:
(SELECT...... ORDER BY ...) UNION ALL (SELECT ...... ORDER BY .....) 
y efectivamente une los resultados de ambas consultas, uno a continuación de la otra, pero deja de respetar los ORDER BY de cada consulta. Primero aparecen los resultados de la primera consulta pero sin orden, y a continuación los de la segunda, sin mezclarse con los de la primera, pero también sin orden.

¿Cómo puedo hacer que UNION ALL siga respetando lo que establecen los ORDER BY de casa consulta por separado?

Gracias desde ya.
  #2 (permalink)  
Antiguo 04/03/2009, 11:51
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: UNION ALL no respeta orden de ORDER BY???

El ORDER BY no va en las subconsultas, sino al final del SELECT principal, si lo tiene, o al final del último SELECT.

Si pones ORDER BY intermedios, lo único que estás haciendo es ralentizar la consulta, porque es una cláusula que consume muchos recursos. Si no es estrictamente necesaria para realizar algo dentro de la subconsulta, entonces no la pongas allí.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 05/03/2009, 07:27
 
Fecha de Ingreso: marzo-2009
Mensajes: 10
Antigüedad: 15 años, 8 meses
Puntos: 0
Respuesta: UNION ALL no respeta orden de ORDER BY???

Yo también quiero ordenar los dos selects independientemente. Si pongo el order by al final, se ordena toda la consulta mezclandose los registros de los dos selects y esto es algo que no quiero. ¿Cómo puedo ordenar los dos selects independientemente? Gracias.
  #4 (permalink)  
Antiguo 05/03/2009, 08:19
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 17 años
Puntos: 2658
Respuesta: UNION ALL no respeta orden de ORDER BY???

Cita:
Iniciado por cuernut Ver Mensaje
Yo también quiero ordenar los dos selects independientemente. Si pongo el order by al final, se ordena toda la consulta mezclandose los registros de los dos selects y esto es algo que no quiero. ¿Cómo puedo ordenar los dos selects independientemente? Gracias.
No usando UNION ALL, sino UNION. Eso hará un encadenamiento de los bloques de datos.
Las únicas condiciones son: a) Tener el mismo número de columnas, b) El mismo tipo de datos en el mismo orden...
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #5 (permalink)  
Antiguo 05/03/2009, 08:28
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años, 7 meses
Puntos: 300
Respuesta: UNION ALL no respeta orden de ORDER BY???

El problema, si no he entendido mal, es que quieres ordenar por dos campos distintos y luego hacer el union all.
Esto es una chapuza que puede funcionar:
(
SELECT campo1, campo2, 'a' AS tabl
FROM tabla1
)
UNION ALL (

SELECT campo1, campo2, 'b' AS tabl
FROM tabla2
)
ORDER BY tabl, if( tabl = 'a', campo1, campo2 )

Uso un valor absoluto, ese tabl, a y b, para establecer un orden entre las tablas y luego para condicionar la elección del campo que sirve para ordenar.
  #6 (permalink)  
Antiguo 05/03/2009, 09:03
 
Fecha de Ingreso: marzo-2009
Mensajes: 10
Antigüedad: 15 años, 8 meses
Puntos: 0
Respuesta: UNION ALL no respeta orden de ORDER BY???

Gracias por responder tan rápido. Tanto si utilizo UNION como UNION ALL el resultado es el mismo pues no hay datos repetidos y en los dos cosas o no se ordenan o si los ordeno se mezclan los dos selects.
En cuando al script de jurena, me sale el siguiente error (adaptándolo a tu ejemplo):
Table 'tabla1' from one of the SELECTs cannot be used in global ORDER clause

Alguna idea. Gracias.
  #7 (permalink)  
Antiguo 05/03/2009, 09:37
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años, 7 meses
Puntos: 300
Respuesta: UNION ALL no respeta orden de ORDER BY???

Pon los nombres de tus tablas, de tus campos, por cuál quieres que ordene de cada uno y la sintaxis que utilizas para que te dé ese error.
  #8 (permalink)  
Antiguo 05/03/2009, 09:48
 
Fecha de Ingreso: marzo-2009
Mensajes: 10
Antigüedad: 15 años, 8 meses
Puntos: 0
Respuesta: UNION ALL no respeta orden de ORDER BY???

Pongo el codigo para que quede más claro:

(select ciclistes.nom,CONCAT('Port: ',ports.nom) AS guanyat,ports.altura AS 'altura o KM en metres' from ciclistes,ports where ports.ciclista=ciclistes.dorsal) UNION ALL (select ciclistes.nom,CONCAT('Etapa: ',etapes.eixida),kms*1000 AS 'altura o KM en metres' from ciclistes,etapes where etapes.ciclista=ciclistes.dorsal);

Tengo 3 columnas:
1. El nombre de los ciclistas.
2. El puerto de montaña y las etapas ganadas por el ciclista (en esta columna han de aparecer primero los puertos y después las etapas sin mezclarse).
3. La altura de los puertos o los kms en metros de las etapas. Esta es la columna que quiero que aparezca ordenada: en el primer select ordenada descendentemente la altura y en el segundo select los kms en metros tambien descendentemente (sin que se mezclen los selects).

Bien es un poco complicado y no se si se podra hacer. Gracias.
  #9 (permalink)  
Antiguo 05/03/2009, 12:39
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años, 7 meses
Puntos: 300
Respuesta: UNION ALL no respeta orden de ORDER BY???

Cita:
Iniciado por cuernut Ver Mensaje
Pongo el codigo para que quede más claro:

(select ciclistes.nom,CONCAT('Port: ',ports.nom) AS guanyat,ports.altura AS 'altura o KM en metres' from ciclistes,ports where ports.ciclista=ciclistes.dorsal) UNION ALL (select ciclistes.nom,CONCAT('Etapa: ',etapes.eixida),kms*1000 AS 'altura o KM en metres' from ciclistes,etapes where etapes.ciclista=ciclistes.dorsal);

Tengo 3 columnas:
1. El nombre de los ciclistas.
2. El puerto de montaña y las etapas ganadas por el ciclista (en esta columna han de aparecer primero los puertos y después las etapas sin mezclarse).
3. La altura de los puertos o los kms en metros de las etapas. Esta es la columna que quiero que aparezca ordenada: en el primer select ordenada descendentemente la altura y en el segundo select los kms en metros tambien descendentemente (sin que se mezclen los selects).

Bien es un poco complicado y no se si se podra hacer. Gracias.
No sé si te habré entendido bien, pero prueba esto (yo no lo he probado):

select ciclistes.nom,'A' as CLAS, CONCAT('Port: ',ports.nom) AS guanyat,ports.altura AS altura_o_KM_en_metres from ciclistes,ports where ports.ciclista=ciclistes.dorsal) UNION ALL (select ciclistes.nom,'B' as CLAS, CONCAT('Etapa: ',etapes.eixida),kms*1000 AS altura_o_KM_en_metres from ciclistes,etapes where etapes.ciclista=ciclistes.dorsal) order by CLAS, altura_o_KM_en_metres DESC
  #10 (permalink)  
Antiguo 05/03/2009, 23:17
rqd
 
Fecha de Ingreso: julio-2008
Mensajes: 228
Antigüedad: 16 años, 4 meses
Puntos: 8
Respuesta: UNION ALL no respeta orden de ORDER BY???

por que no pruebas crear una vista (CREATE VIEW) con la consulta que quieres y luego hacer el SELECT de la vista. Este deberá ser ordenado.
  #11 (permalink)  
Antiguo 06/03/2009, 01:41
Colaborador
 
Fecha de Ingreso: marzo-2008
Ubicación: Cáceres
Mensajes: 3.735
Antigüedad: 16 años, 7 meses
Puntos: 300
Respuesta: UNION ALL no respeta orden de ORDER BY???

En el manual de MySQL, dentro de las aportaciones de usuarios, se ofrecen otras dos, que creo que harán lo mismo que la que te propuse, aunque se utilizan subconsultas:

Cita:
Posted by Phil McCarley on February 28 2006 6:37am [Delete] [Edit]

In addition to the above comment regarding the ORDERing of individual SELECTS, I was after a way to do exactly what is says wouldn't work. I have two playlists, and to get the correct order I need to use two different ORDER clauses, also I wanted to use the DISTINCT functionality of the UNION syntax.

What I needed was the contents of each playlist to be ordered in there specific way, while the first appeared wholly before the second. Also, I couldn't use the various tricks of adding extra colums to sort on because that left me with non-unique rows and therefore if the same entry was in both lists, the duplicate didn't get removed.

How I overcame this was to use subqueries, as follows:

SELECT song_id FROM
(SELECT song_id FROM play_immediate
ORDER BY play_id DESC) AS t1

UNION

SELECT song_id FROM
(SELECT song_id FROM play_later
ORDER BY play_id) AS t2

And using this I am able to sort each list differently, one ascending and one descending, keep the 'immediate' list before the 'later' list but still remove all duplicates.

Hope this helps others.



Posted by James McGuigan on June 14 2006 9:39am [Delete] [Edit]

If you want to run a WHERE statement on the result of a UNION, you can make the union into a subquery like such:

SELECT * FROM ((
SELECT * FROM table1
WHERE ...
ORDER BY ...
LIMIT ...
) UNION (
SELECT * FROM table2
WHERE ...
ORDER BY ...
LIMIT ...
)) as t
WHERE ...
ORDER BY ...
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 14:36.