2013-07-19 55 views
2

我想知道是否有可能像這樣從同一個表計算行:計數多行

我有一個表命名爲tickets包含標題,內容等等...

有一個名爲status的列,其中狀態可以是:

new 
waiting 
assign 
closed 
solved 

我希望能夠count

new tickets 
waiting tickets 
assign tickets 
closed tickets 
solved tickets 

和同一個請求中的所有票據,它有可能還是應該爲每個請求提出新的請求? 謝謝!

回答

2

做在一個請求,因爲這是(幾乎總是)比運行多個查詢更高效。得到的結果爲單排

一種方法是這樣的:

SELECT SUM(status='new' ) AS count_new 
    , SUM(status='waiting') AS count_waiting 
    , SUM(status='assign' ) AS count_assign 
    FROM tickets 

如果您還需要所有門票的數量,你可以將它添加到SELECT列表:

 , SUM(1)     AS count_all 

如果你也想加起來新的和等待在一起,還可以補充一點:

 , SUM(status IN ('new','waiting')) AS count_new_or_waiting 

注意

SUM(a=b) 

基本上是簡寫:

SUM(IF(a=b,1,0)) 

有一個細微的差別,在於前者將返回NULL,當A或B爲空,所以有返回一個潛在的NULL,SUM有可能是NULL的理論可能性。一個簡單的方法,以任何NULL轉換爲0是使用IFNULL函數:

IFNULL(SUM(a=b)) 

避免NULL將使用MySQL的「空安全平等」比較的另一種方式,

SUM(a<=>b) 

如果你想便攜式的東西,那麼你最好的選擇將是soemthing SQL-92兼容:

SUM(CASE WHEN a=b THEN 1 ELSE 0 END) 

一般approac h是一樣的。我們正在查看滿足謂詞的每一行(例如,我們可能有一個日期範圍或行,或某個特定的商店,或類似的東西)。我們正在檢查每一行以查看它是否應計入特定的桶中。一行可以計算在多個桶中(如上所示)。

此方法(IMO)的優點之一是,對於沒有任何行的狀態,查詢將返回零計數。其他方法省略了這一行,我認爲這使得處理行的代碼更難理解。處理來自這個查詢的結果集使得代碼更直接。


上面的例子使用MySQL特有的語法。 (更便攜)ANSI等價物並不簡單。有些人可能會爭辯說ANSI語法更易於理解,特別是對於那些比MySQL更熟悉DBMS的人。

SELECT SUM(CASE WHEN status = 'new'  THEN 1 ELSE 0 END) AS count_new 
     , SUM(CASE WHEN status = 'waiting' THEN 1 ELSE 0 END) AS count_waiting 
    FROM tickets 

這種模式可以通過一些分組可以擴展到這些計數(對於一個部門,一個客戶,一個客戶類型)。我們可以添加一個謂詞(WHERE子句)來獲取行的子集,或者我們可以在SELECT列表中添加一個表達式expr,並添加一個GROUP BY expr

例如,對於每個不同的值「優先級」例如,獲得票數計數。關鍵,緊急重要,LOW

SELECT t.priority 
     , SUM(CASE WHEN t.status = 'new'  THEN 1 ELSE 0 END) AS count_new 
     , SUM(CASE WHEN t.status = 'waiting' THEN 1 ELSE 0 END) AS count_waiting 
    FROM tickets t 
    GROUP BY t.priority 
    ORDER BY IF(t.status='urgent',1,2), t.status 

(在order by子句將整理「緊急」第一即第一個表達式。)

通過這種方法,在「循環處理」不是在不同計數,而是現在在分組列上。這一結果使得集方便的代碼,如果該網頁會顯示這樣的事情:

Priority  New Waiting Assign Total 
URGENT  1  0  0  1 
CRITICAL  0  0  1  1 
IMPORTANT 12  7  3  22 
LOW   77  1048  2  1127 
1

是的,這是group by功能是什麼:

select status, count(*) status_count 
from tickets 
group by status 
1

試試這個.....

SELECT status AS Word, 
COUNT(status) AS Frequency FROM tickets 
GROUP BY status; 
0

使用GROUP BYWITH ROLLUP獲得總計數:

SELECT status, COUNT(status) AS count_status 
FROM tickets 
GROUP BY status WITH ROLLUP;