做在一個請求,因爲這是(幾乎總是)比運行多個查詢更高效。得到的結果爲單排
一種方法是這樣的:
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