Navicat Premium是一个可连接多种数据库的管理工具,它可以让你以单一程序同时连接到MySQL、Oracle及PostgreSQL数据库,让管理不同类型的数据库更加的方便。
在上篇文章中,我们使用了原生COUNT()函数的不同变体来计算一个MySQL表中的行数。在这篇文章中,我们将以更复杂的方式使用COUNT()函数来计算唯一值以及满足条件的值。
不同计数
COUNT(DISTINCT)函数返回具有唯一非空值的行数。因此,包含DISTINCT关键字将从计数中删除重复的行。它的语法是:
1
|
COUNT
(
DISTINCT
expr,[expr...])
|
与常规COUNT()函数一样,上面的expr参数可以是任何给定的表达式,包括特定的列、所有列(*)、函数返回值或表达式(如IF/CASE 语句)。
一个简单的例子
假设我们有下表的客户:
1
2
3
4
5
6
7
8
9
10
11
|
+
------------+-------------+
| last_name | first_name |
+
------------+-------------+
| Tannen | Biff |
+
------------+-------------+
| McFly | Marty |
+
------------+-------------+
| Brown | Dr. Emmett |
+
------------+-------------+
| McFly | George |
+
------------+-------------+
|
调用COUNT(*)将返回所有行的数目(4),而姓氏上的非重复计数将把姓氏重复的每一行计数为1,这样我们得到的总数为3:
1
2
3
4
5
6
|
SELECT
COUNT
(*),
COUNT
(
DISTINCT
last_name)
FROM
clients;
+
----------+---------------------------+
|
COUNT
(*) |
COUNT
(
DISTINCT
last_name) |
+
----------+---------------------------+
| 4 | 3 |
+
----------+---------------------------+
|
使用表达式的条件计数
如上所述,COUNT()函数参数不限于列名;函数返回值和表达式(如IF/CASE 语句)也是公平的。
这是一个包含多个用户电话号码和性别的表(为了简单起见,限制为两个):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
+
------------+---------+
| tel | sex |
+
------------+---------+
| 7136609221 | male |
+
------------+---------+
| 7136609222 | male |
+
------------+---------+
| 7136609223 | female |
+
------------+---------+
| 7136609228 | male |
+
------------+---------+
| 7136609222 | male |
+
------------+---------+
| 7136609223 | female |
+
------------+---------+
|
假设我们想要构建一个查询,告诉我们表中有多少不同的男女。该人员通过其电话('tel')号码进行识别。同一个“tel”可能出现多次,但该tel的性别只应计算一次。
这里有一个选项,对每列使用不同的计数:
1
2
3
4
|
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语句将生成以下内容:
1
2
3
4
5
|
+
--------------+------------+---------------+
| gender_count | male_count | female_count |
+
--------------+------------+---------------+
| 4 | 3 | 1 |
+
--------------+------------+---------------+
|
分组并包括总计
还可以使用GROUP BY垂直堆叠计数:
1
2
3
4
5
6
7
8
9
10
11
|
+
---------+-------+
| GroupId |
Count
|
+
---------+-------+
| 1 | 5 |
+
---------+-------+
| 2 | 4 |
+
---------+-------+
| 3 | 7 |
+
---------+-------+
| Total: | 11 |
+
---------+-------+
|
“total:”是使用SQL GROUPING()函数生成的,该函数添加在MySQL 8.0.1中。它将表示超级聚合行(由汇总生成)中所有值的集合的空值与常规行中的空值区分开来。
以下是完整的SQL:
1
2
3
4
5
6
7
8
|
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
|
下篇文章,我们将从多个表和视图中获取行计数。