2013-06-19 29 views
1

假設一個簡單的例子,例如表bug有一列status,可以是openfixed
如果我想知道有多少錯誤是開放的,我只是做:以1行和不同列顯示結果

select count(*) as open_bugs from bugs where status = 'open';

如果我想知道有多少蟲子打開我簡單地做:

select count(*) as closed_bugs from bugs where status = 'closed';

如果什麼都想知道多少開多少收存在這樣的返回查詢的2列的結果,即

Open | Closed| 
    60 180 

這樣做的最佳方法是什麼? UNION串接的結果,所以它不是我想要

回答

4

試試這個

select count(case when status = 'open' then 1 end) open_bugs, 
count(case when status = 'closed' then 1 end) closed_bugs 
from bugs 
+0

的情況下基本上越過每一行並創建一個1/0s的「不可見」行,並在外部的'select'中加上它們,對吧? – Cratylus

+0

是的,這將返回1匹配的條件和null爲他人。當你計算它會做計數有價值的行 –

8

這可以通過使用與您的聚合函數CASE表達式做什麼。這將行轉換爲列:

​​

這也使用原來的查詢中寫:

select 
    max(case when status = 'open' then total end) open_bugs, 
    max(case when status = 'closed' then total end) closed_bugs 
from 
(
    select status, count(*) as total from bugs where status = 'open' group by status 
    union all 
    select status, count(*) as total from bugs where status = 'closed' group by status 
) d 
+0

案件基本上遍及每一行,並創建一個「不可見」行與1/0s和外部'選擇'它總結它們,對吧? – Cratylus

+1

由於這是彙總數據,因此只包含與案例中的「狀態」匹配的行。它只是將where過濾器移到聚合函數。 – Taryn

+1

不是我會用第二個版本來推廣非標準的SQL ......但是,第一個版本上的+1。 –

7

除此之外聚集在整個表CASE變種,還有另一種方式。要使用您的查詢,並把他們在另一個內部SELECT

SELECT 
    (SELECT COUNT(*) FROM bugs WHERE status = 'open') AS open_bugs, 
    (SELECT COUNT(*) FROM bugs WHERE status = 'closed') AS closed_bugs 
FROM dual  -- this line is optional 
; 

它的優點是你可以從不同的表包裝計數或在一個單一的查詢連接。

效率可能也有差異(更糟或更好)。測試你的表格和索引。

您還可以使用GROUP BY得到不同行的種種罪狀(如UNION你提到),然後用另一個聚集轉動一行結果:

SELECT 
    MIN(CASE WHEN status = 'open' THEN cnt END) AS open_bugs, 
    MIN(CASE WHEN status = 'closed' THEN cnt END) AS closed_bugs 
FROM 
    (SELECT status, COUNT(*) AS cnt 
    FROM bugs 
    WHERE status IN ('open', 'closed') 
    GROUP BY status 
) AS g