Unirse a la izquierda y obtener registros totales en la tabla unida

Estoy usando la siguiente consulta:

SELECT `users`.`id` as id 
FROM (`users`) 
    LEFT JOIN `work_orders` 
        ON `users`.`id` = `work_orders`.`assigned_to` 
WHERE (work_orders.status = 'approved' 
        OR work_orders.status = 'scheduled' 
        OR work_orders.status = 'published') 
    AND work_orders.is_paid = 0 
ORDER BY `users`.`id` DESC 
LIMIT 30

Pero con esta consulta obtengo múltiples registros para cada users si tienen mas de uno work_orders. ¿Qué debo hacer para enumerar solo users una vez que tienen mas de uno work_orders?

preguntado el 12 de junio de 12 a las 20:06

4 Respuestas

Podrías usar la cláusula DISTINCT:

SELECT DISTINCT(users.id) as id FROM (`users`) LEFT JOIN `work_orders` ON `users`.`id` = `work_orders`.`assigned_to` WHERE (work_orders.status = 'approved' OR work_orders.status = 'scheduled' OR work_orders.status = 'published') AND work_orders.is_paid = 0 ORDER BY `users`.`id` DESC LIMIT 30

Respondido el 12 de junio de 12 a las 20:06

¿Puede explicarme la diferencia entre usar Agrupar por As respondido por claas y distinto? - Yalamber

Bueno el GROUP BY le permitirá ejecutar funciones agregadas en cada grupo. Sin embargo, dado que no estás haciendo eso, un DISTINCT parecía el mejor enfoque. Creo que en este caso, los dos serían bastante similares en términos de planes de ejecución, pero no soy un experto en mySQL, así que no puedo asegurarlo. Yo usaría el que más te guste. - mike christensen

Puede agregar una declaración GROUP BY para filtrar por ID de usuario porque esto es todo lo que le interesa.

SELECT `users`.`id` as id 
FROM (`users`) LEFT JOIN `work_orders` ON `users`.`id` = `work_orders`.`assigned_to` 
WHERE (work_orders.status = 'approved' 
  OR work_orders.status = 'scheduled' 
  OR work_orders.status = 'published') 
  AND work_orders.is_paid = 0 
GROUP BY `users`.`id`
ORDER BY `users`.`id` DESC LIMIT 30

Respondido el 12 de junio de 12 a las 20:06

Hola, ¿puedes explicarme la diferencia entre usar distinto como respondió mike y agrupar por - Yalamber

Utilicé este que funciona como se esperaba. Me gustaría saber cuál es la mejor opción de otras respuestas porque también funcionan: Yalamber

Si usa la declaración de grupo, también debería poder contar la cantidad de entradas por usuario (creo que usando COUNT (*)), que podría ser una buena extensión. De lo contrario, la instrucción DISTINCT también debería funcionar. No estoy seguro de cuál se comporta mejor con respecto al rendimiento, pero no espere grandes diferencias. - Claas Wilke

Intente usar GROUP BY

SELECT `users`.`id` as id 
  FROM (`users`) 
  LEFT JOIN `work_orders` 
    ON `users`.`id` = `work_orders`.`assigned_to` 
 WHERE ( work_orders.status = 'approved' 
       OR work_orders.status = 'scheduled' 
       OR work_orders.status = 'published' ) 
   AND work_orders.is_paid = 0 
GROUP BY `users`.`id` DESC 
LIMIT 30

Respondido el 12 de junio de 12 a las 20:06

SELECT `users`.`id` as id 
  FROM (`users`) 
  WHERE exists ( select 1 from `work_orders` where work_orders.status 
                     in  ('approved' ,'scheduled' ,'published' ) 
                     AND work_orders.is_paid = 0 
                     and `work_orders`.`assigned_to` =`users`.`id` )
 ORDER BY `users`.`id` DESC 
 LIMIT 30

Respondido el 12 de junio de 12 a las 20:06

Este parece más complejo, ¿funcionará en todas las versiones de mysql? - Yalamber

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.