2010-08-30 58 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知道沒有進一步調查),但至少也應該給有用的結果;-)