2011-06-18 5 views
5

Estoy intentando UNION dos consultas que contienen ORDER BY's. Como he descubierto, no puede ordenar por consultas que forman parte de UNION. Simplemente no sé cómo más hacer esta consulta. Déjame explicarte lo que estoy tratando de hacer.MySQL UNION 2 consultas que contienen ORDER BYs

  1. Estoy tratando de seleccionar los 40 perfiles más recientes y de esa lista seleccionar un conjunto aleatorio de 20. entonces quiero que la unión con:
  2. Seleccionar 40 perfiles de azar en el que el perfil no está comprendida en el original 40 perfiles más recientes consultados en el primer conjunto
  3. Ordene al azar ese conjunto completo de 60 registros.

Soy consciente de las ramificaciones de la eficiencia de la utilización de la función rand()

SELECT profileId 
    FROM (SELECT profileId 
      FROM profile profile2 
     WHERE profile2.profilePublishDate <= Now() 
     ORDER BY profile2.profilePublishDate DESC 
     LIMIT 0,40) AS profile1 
ORDER BY RAND() 
    LIMIT 0,20 
UNION (SELECT profileId 
     FROM profile profile4 
     WHERE profileId NOT IN (SELECT profileId 
            FROM profile profile4 
           WHERE profile4.profilePublishDate <= Now() 
           ORDER BY profile4.profilePublishDate DESC 
           LIMIT 0,40)  
    ORDER BY RAND()  
     LIMIT 0,40) as profile3 
ORDER BY RAND() 

ACTUALIZACIÓN: Esta es la solución basada en la ayuda de Abhay a continuación (gracias Abhay):

SELECT * 
FROM 
(
    (
     SELECT profileId 
     FROM 
     (
      SELECT profileId 
      FROM profile profile2 
      WHERE profile2.profilePublishDate <= Now() 
      ORDER BY profile2.profilePublishDate DESC 
      LIMIT 0,40 
     ) AS profile1 
     ORDER BY RAND() 
     LIMIT 0,20 
    ) 
    UNION 
    (
     SELECT profileId 
     FROM profile profile4 
     WHERE profileId NOT IN (
      SELECT * FROM 
      (
      SELECT profileId 
      FROM profile profile4 
      WHERE profile4.profilePublishDate <= Now() 
      ORDER BY profile4.profilePublishDate DESC 
      LIMIT 0,40 
      ) AS temp2 
     ) 
     ORDER BY RAND()  
     LIMIT 0,40 
    ) 
) TEMP 
ORDER BY RAND(); 

Respuesta

5

Esta es su solución:

SELECT * 
FROM 
(
    **(** 
     SELECT profileId 
     FROM 
     (
      SELECT profileId 
      FROM profile profile2 
      WHERE profile2.profilePublishDate <= Now() 
      ORDER BY profile2.profilePublishDate DESC 
      LIMIT 0,40 
     ) AS profile1 
     ORDER BY RAND() 
     LIMIT 0,20 
    **)** 
    UNION 
    (
     SELECT profileId 
     FROM profile profile4 
     WHERE profileId NOT IN (
      SELECT profileId 
      FROM profile profile4 
      WHERE profile4.profilePublishDate <= Now() 
      ORDER BY profile4.profilePublishDate DESC 
      LIMIT 0,40 
      ) 
     ORDER BY RAND()  
     LIMIT 0,40 
    ) 
) TEMP 
ORDER BY RAND(); 

Los cambios que he hecho son:

  1. cada una de sus preguntas que forman parte de la Unión debe ser encerrada entre paréntesis (en negrita para la primera consulta, el segundo ya está encerrado)
  2. elimina el alias profile3 para su segunda consulta
  3. para la final ORDER BY RAND(), debe crear XX e UNION resultados en una tabla derivada; Lo he dado TEMP como el alias

No he probado la consulta anterior, pero espero que funcione. Déjame saber tus hallazgos.

+1

Gracias - Su solución resolvió mi problema sin embargo surgió un nuevo error (Esta versión de MySQL aún no admite 'LIMIT & IN/ALL/ANY/ALGUNA subconsulta ') que también he resuelto con otro seleccionar y publicado la consulta completa anterior en mi publicación original. Gracias por su ayuda para resolver esto. – Cheeky

+0

@Cheeky: Sí, esta es la manera de resolverlo, con las limitaciones que plantea MySQL :) –

1

Puede encerrar toda la consulta en otra selección (para hacer es una subselección) y ORDER BY RAND() en ese conjunto de resultados. Sin embargo, esto es bastante intrincado (muchas declaraciones aleatorias ORDER BY cuando solo se necesita uno), por lo que es menos intensivo en el uso del procesador recopilar el conjunto de datos ordenados (es decir, UNION de profile1 y profile3) en una matriz en el idioma de su elección. aleatorizar ese orden de esa matriz.

+0

Necesita el 'ORDER BY RAND()' interno –

+0

@ypercube ¿por qué se requiere el 'ORDER BY' interno cuando se reordena todo el conjunto de resultados? – Andy

+0

porque se usa en combinación con 'LIMIT 40' para elegir 40 filas aleatorias de una parte de la tabla y 20 filas aleatorias de otra (con' LIMIT 20'). –