return count 0 with mysql group by

被刻印的时光 ゝ 提交于 2019-12-17 16:45:20

问题


database table like this

============================
= suburb_id   |   value
= 1           |    2
= 1           |    3
= 2           |    4
= 3           |    5

query is

SELECT COUNT(suburb_id) AS total, suburb_id 
  FROM suburbs 
 where suburb_id IN (1,2,3,4) 
GROUP BY suburb_id

however, while I run this query, it doesn't give COUNT(suburb_id) = 0 when suburb_id = 0 because in suburbs table, there is no suburb_id 4, I want this query to return 0 for suburb_id = 4, like

============================
= total       |   suburb_id
= 2           |    1
= 1           |    2
= 1           |    3
= 0           |    4

回答1:


A GROUP BY needs rows to work with, so if you have no rows for a certain category, you are not going to get the count. Think of the where clause as limiting down the source rows before they are grouped together. The where clause is not providing a list of categories to group by.

What you could do is write a query to select the categories (suburbs) then do the count in a subquery. (I'm not sure what MySQL's support for this is like)

Something like:

SELECT 
  s.suburb_id,
  (select count(*) from suburb_data d where d.suburb_id = s.suburb_id) as total
FROM
  suburb_table s
WHERE
  s.suburb_id in (1,2,3,4)

(MSSQL, apologies)




回答2:


This:

SELECT  id, COUNT(suburb_id)
FROM    (
        SELECT  1 AS id
        UNION ALL
        SELECT  2 AS id
        UNION ALL
        SELECT  3 AS id
        UNION ALL
        SELECT  4 AS id
        ) ids
LEFT JOIN
        suburbs s
ON      s.suburb_id = ids.id
GROUP BY
        id

or this:

SELECT  id,
        (
        SELECT  COUNT(*)
        FROM    suburb
        WHERE   suburb_id = id
        )
FROM    (
        SELECT  1 AS id
        UNION ALL
        SELECT  2 AS id
        UNION ALL
        SELECT  3 AS id
        UNION ALL
        SELECT  4 AS id
        ) ids

This article compares performance of the two approaches:

  • Aggregates: subqueries vs. GROUP BY

, though it does not matter much in your case, as you are querying only 4 records.




回答3:


Query:

select case
         when total is null then 0
         else total
       end as total_with_zeroes,
       suburb_id
from (SELECT COUNT(suburb_id) AS total, suburb_id 
        FROM suburbs 
       where suburb_id IN (1,2,3,4) 
    GROUP BY suburb_id) as dt



回答4:


@geofftnz's solution works great if all conditions are simple like in this case. But I just had to solve a similar problem to generate a report where each column in the report is a different query. When you need to combine results from several select statements, then something like this might work.

You may have to programmatically create this query. Using left joins allows the query to return rows even if there are no matches to suburb_id with a given id. If your db supports it (which most do), you can use IFNULL to replace null with 0:

select IFNULL(a.count,0), IFNULL(b.count,0), IFNULL(c.count,0), IFNULL(d.count,0)
from (select count(suburb_id) as count from suburbs where id=1 group by suburb_id) a,
 left join (select count(suburb_id) as count from suburbs where id=2 group by suburb_id) b on a.suburb_id=b.suburb_id
 left join (select count(suburb_id) as count from suburbs where id=3 group by suburb_id) c on a.suburb_id=c.suburb_id
 left join (select count(suburb_id) as count from suburbs where id=4 group by suburb_id) d on a.suburb_id=d.suburb_id;

The nice thing about this is that (if needed) each "left join" can use slightly different (possibly fairly complex) query.

Disclaimer: for large data sets, this type of query might have not perform very well (I don't write enough sql to know without investigating further), but at least it should give useful results ;-)



来源:https://stackoverflow.com/questions/3597577/return-count-0-with-mysql-group-by

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!