Navicat 部落格

2018 年 4 月 4 日,由 Robert Gravelle 撰寫

在上週的「在 MySQL 中取得列計數」文章中,我們採用了原生的 COUNT() 函式的不同變體來計算一個 MySQL 資料表中的列數。在今天的後續文章中,我們將以更複雜的方式使用 COUNT() 函式來計算唯一值以及符合條件的值。

計算不同的項目

COUNT(DISTINCT) 函式傳回具有唯一非 NULL 值的列數。因此,包含 DISTINCT 關鍵字可以消除計數中的重複列。它的語法是:

COUNT(DISTINCT expr,[expr...])

與正規 COUNT() 函式一樣,上面的 expr 參數可以是任何特定的運算式,包括指定的欄、所有欄(*)、函式傳回值或運算式(如 IF/CASE 語句)。

簡單的例子

假設我們有以下 clients 資料表:

+------------+-------------+
| last_name  | first_name  |
+------------+-------------+
| Tannen     | Biff        |
+------------+-------------+
| McFly      | Marty       |
+------------+-------------+
| Brown      | Dr. Emmett  |
+------------+-------------+
| McFly      | George      |
+------------+-------------+

調用 COUNT(*) 將傳回所有列的數量(4),而在 last_name 上使用 COUNT DISTINCT 將計算重複姓氏的列為 1,這樣我們得到總數 3:

SELECT COUNT(*), COUNT(DISTINCT last_name) FROM clients;
+----------+---------------------------+
| COUNT(*) | COUNT(DISTINCT last_name) |
+----------+---------------------------+
| 4        | 3                         |
+----------+---------------------------+

使用運算式的條件性計算數目

如上所述,COUNT() 函式參數不限於欄的名稱,也可以是函式傳回值和運算式(如 IF/CASE 語句)。

這是一個包含多個使用者的電話號碼和性別的資料表(為簡單起見只有兩欄):

+------------+---------+
| tel        | sex     |
+------------+---------+
| 7136609221 | male    |
+------------+---------+
| 7136609222 | male    |
+------------+---------+
| 7136609223 | female  |
+------------+---------+
| 7136609228 | male    |
+------------+---------+
| 7136609222 | male    |
+------------+---------+
| 7136609223 | female  |
+------------+---------+

假設我們想要建立一個查詢,讓我們知道資料表中有多少不同的女性和男性。使用者是透過他們的電話號碼(tel)識別。同一個「tel」可能會出現多次,但 tel 的性別應該只計算一次。

這是為每欄使用獨立的 COUNT DISTINCT 的一個選項:

SELECT COUNT(DISTINCT tel) gender_count,
       COUNT(DISTINCT CASE WHEN gender = 'male'   THEN tel END) male_count,
       COUNT(DISTINCT CASE WHEN gender = 'female' THEN tel END) female_count
FROM people

這個 SELECT 語句將產生以下結果:

+--------------+------------+---------------+
| gender_count | male_count | female_count  |
+--------------+------------+---------------+
| 4            | 3          | 1             |
+--------------+------------+---------------+

額外提示-分組和包括總計

你還可以使用 GROUP BY 垂直堆疊計數:

+---------+-------+
| GroupId | Count |
+---------+-------+
| 1       | 5     |
+---------+-------+
| 2       | 4     |
+---------+-------+
| 3       | 7     |
+---------+-------+
| Total:  | 11    |
+---------+-------+

「Total:」是使用 SQL GROUPING() 函式產生的,MySQL 8.0.1 加入了該函式。它區分了代表超級彙總列(由 ROLLUP 產生)中所有值集的 NULL 與正規列中的 NULL。

這是完整的 SQL:

Select  Case When Grouping(GroupId) = 1
             Then 'Total:'
             Else GroupId
        End As GroupId,
        Count(*) Count
From    user_groups
Group By GroupId With Rollup
Order By Grouping(GroupId), GroupId

下週,我們將從多個資料表和檢視中取得列計數。

Navicat 文章
頻道記錄
分享
部落格封存檔