MySQL: Make subqueries respect grouping (Basic help needed!)

artymarty13 :

Pretty basic Q but I'm just starting with MySql and can't work out how to do this. I am trying to summarise some pickup data and i want to gorup it into months and then show columns for total pickups in that month as well as a breakdown of what materials were picked up. I have tried to do this with subqueries but it shows for each month the total of pickups of the different material types from all time. What is the easiest way to solve this. Ta!

  SELECT
        DATE_FORMAT(pickup.created_at,'%Y-%m') as 'service_year_month',
        count(pickup.id) as total_pickup_id,
        (SELECT COUNT(*) from pickup WHERE pickup.material = "PAPER") as paper_pickups,
        (SELECT COUNT(*) from pickup WHERE pickup.material = "OTHER") as other_pickups,
        (SELECT COUNT(*) from pickup WHERE pickup.material = "PLASTIC") as plastic_pickups,
        (SELECT COUNT(*) from pickup WHERE pickup.material = "WOOD") as wood_pickups,
        (SELECT COUNT(*) from pickup WHERE pickup.material = "GLAS") as glas_pickups,
        (SELECT COUNT(*) from pickup WHERE pickup.material = "METAL") as metal_pickups
    FROM
        pickup
        left join container on
        pickup.container_id = container.id
    WHERE
        container.pickup_mode = 'ON_DEMAND'
    group by service_year_month
    order by service_year_month desc;
forpas :

You can do it with conditional aggregation:

SELECT
  DATE_FORMAT(p.created_at,'%Y-%m') AS service_year_month,
  COUNT(p.id) AS total_pickup_id,
  SUM(p.material = 'PAPER') AS paper_pickups,
  SUM(p.material = 'OTHER') AS other_pickups,
  SUM(p.material = 'PLASTIC') AS plastic_pickups,
  SUM(p.material = 'WOOD') AS wood_pickups,
  SUM(p.material = 'GLAS') AS glas_pickups,
  SUM(p.material = 'METAL') AS metal_pickups
FROM pickup p LEFT JOIN container c
ON p.container_id = c.id AND c.pickup_mode = 'ON_DEMAND'
GROUP BY service_year_month
ORDER BY service_year_month desc;

Also use aliases for the tables to shorten the code and make it more readable.
I moved the condition:

c.pickup_mode = 'ON_DEMAND'

to the ON clause because when you use it in the WHERE clause it changes the join to an INNER JOIN.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=372255&siteId=1