2010-08-30 80 views
9

数据库表这样返回计数0与MySQL组由

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

查询

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

然而,当我运行此查询,它并没有给COUNT(suburb_id)= 0时suburb_id = 0 因为在郊区表,没有suburb_id 4,我想这个查询为suburb_id = 4返回0,像

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

你是否有另一张桌子,提供所有郊区的信息?或者是surburb 4 Sir Not-In-In-This-Database? – Powerlord 2010-08-30 14:06:50

回答

10

GROUP BY需要使用行,因此如果某个类别没有行,则不会获得计数。将where子句视为限制源行被分组在一起之前。 where子句没有提供分组的依据列表。

你可以做的是写一个查询来选择类别(郊区),然后在子查询中进行计数。 (我不知道MySQL的这种支持是等)

喜欢的东西:

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,道歉)

+0

对于简单情况+1,但是当您需要组合几个更复杂的查询时,请参阅我的答案。 – Upgradingdave 2012-08-24 02:26:13

+0

这正是我期待的! – thenetimp 2013-04-05 18:53:59

1

查询:

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 
+1

因为没有'suburb_id'为4的记录,所以内部查询将不会返回NULL以供CASE表达式捕获。 – 2010-08-30 03:11:03

4

此:

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 

或者这个:

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 

本文比较了两种方法的性能:

,尽管它在你的情况没有多大意义的,因为你是唯一的查询记录4

+0

普克。但是正确的。 Mysql有这么多“没有标准”的时髦功能,它怎么没有系列生成器呢?!顺便说一句,至少一些代码简洁,你可以从你的'UNION'中移除'ALL'(所有的值都是唯一的,并且已经排序,所以结果将与'UNION'相同),并且除了第一个'AS ID'。你可以在内嵌它:'FROM(SELECT 1 AS id UNION SELECT 2 UNION SELECT 3 UNION SELECT 4)ids'。 – Bohemian 2012-08-24 03:39:59

1

@ geofftnz的解决方案在所有情况下都很简单,就像在这种情况下一样。但是我只需要解决一个类似的问题来生成一个报告,其中报告中的每一列都是一个不同的查询。当你需要结合几个选择语句的结果时,这样的事情可能会起作用。

您可能必须以编程方式创建此查询。即使没有与给定ID的suburb_id匹配,使用左连接也允许查询返回行。如果你的数据库支持的话(其中大多数人),你可以使用IFNULL用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; 

关于这样做的好处是,(如果需要)每个“左连接”可以使用略有不同(可能相当复杂)的查询。

免责声明:对于大数据集,这种类型的查询可能不执行得很好(我写得不够SQL知道没有进一步调查),但至少也应该给有用的结果;-)