下载Navicat Premium最新版本
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 |
下篇文章,我们将从多个表和视图中获取行计数。
来源:oschina
链接:https://my.oschina.net/u/4009527/blog/3009901