要求統計所有分類下的數量,如果分類下沒有對應的數據也要展示。這種問題在日常的開發中很常見,每次寫每次忘,所以在此記錄下。 這種統計往往不能直接group by,因為有些類別可能沒有對應的數據 這裡有兩個思路(如果您有更好的方法,請一定要告訴我,求求了): 每種類型分別統計,用union 連接(比較適 ...
要求統計所有分類下的數量,如果分類下沒有對應的數據也要展示。這種問題在日常的開發中很常見,每次寫每次忘,所以在此記錄下。
這種統計往往不能直接group by,因為有些類別可能沒有對應的數據
這裡有兩個思路(如果您有更好的方法,請一定要告訴我,求求了):
-
每種類型分別統計,用union 連接(比較適合類型已知、不多且確定的)
過UNION操作符組合了三個獨立的查詢,每個查詢都基於數據表計算了不同條件下的數量,簡單粗暴,但不是很推薦
SELECT `status` `key`,COUNT(id) amount FROM 數據表 WHERE `status` IS NULL UNION SELECT 1 `key`,COUNT(id) amount FROM 數據表 WHERE `status` = 1 UNION SELECT 2 `key`,COUNT(id) amount FROM 數據表 WHERE `status` = 2 UNION SELECT 3 `key`,COUNT(id) amount FROM 數據表 WHERE `status` = 3
優化(枚舉類型,left join數據表):
SELECT a.`key`, IFNULL( b.amount, 0 ) amount FROM ( SELECT 1 AS `key` UNION SELECT 2 UNION SELECT 3 ) AS a LEFT JOIN ( SELECT `status` `key`, COUNT( id ) amount FROM 數據表 GROUP BY `status` ) AS b ON a.`key` = b.`key`
性能分析:
第一個SQL語句進行了多次全表掃描(假設索引未覆蓋status欄位)。這種做法可能導致更多的磁碟I/O操作,尤其是當數據量較大時,性能開銷會較高。第二個SQL語句僅對數據表進行了一次掃描,並利用了GROUP BY進行聚合操作,減少了磁碟I/O,理論上在大多數情況下比第一個SQL更高效。
結論:
第二個SQL語句在性能和耗時上通常優於第一個SQL語句,因為它只需要遍歷表一次,並對結果進行一次性聚合,避免了多次全表掃描帶來的性能損失。
若status欄位上有索引,第二個SQL的優勢會更加明顯,因為可以利用索引加速查詢過程。
-
先查類型表,left join數據表,最後對left join後的數據再進行分組,註意:要給右表(數據表)為空時判斷
和第一個的優化版思路是一樣的
SELECT a.id `key`, a.classify_name `name`, COUNT(b.id) `count` FROM 分類表 a LEFT JOIN 數據表 b ON b.`level` = a.id GROUP BY a.id