数据汇总
有时需要对数据库中的数据进行一些统计,比如统计员工总数,统计年龄大于25岁的员工中的最低工资,统计工资大于3800的与昂哦你的平均年龄等。
SQL提供了聚合函数来完成结果集条数、某个字段的最大值、某个字段的最小值、某个字段的平均值及某个字段的合计值等数据统计的功能,SQL标准中规定了下面几种聚合函数:
函数名 说明
MAX 计算字段最大值
MIN 计算字段最小值
AVG 计算字段平均值
SUM 计算字段的合计值
COUNT 统计数据条数
这几个聚合函数都有一个参数,这个参数表示要统计的字段名,比如要统计工资总额,就需要把FSalary作为SUM函数的参数。通过例子来看一下聚合函数的用法:
MAX
第一个例子是插叙年龄大于25岁的员工的最高工资,执行下面的SQL:
SELECT MAX(FSalary) AS MAX_Salary FROM T_Employee WHERE FAge > 25
执行结果:
+------------+
| MAX_Salary |
+------------+
| 8300.00 |
+------------+
AVG
第二个例子我们来统计一下大于3800元的员工的平均年龄,执行下面的SQL:
select AVG(FAge) AS AVG_FAge FROM T_Employee WHERE FSalary >3800;
执行结果:
+----------+
| AVG_FAge |
+----------+
| 27.2000 |
+----------+
SUM
第三个例子我们来统计一下公司每个月应支出的工资的总额,执行下面的SQL:
SELECT SUM(FSalary) FROM T_Employee
执行结果:
+--------------+
| SUM(FSalary) |
+--------------+
| 37300.00 |
+--------------+
APPLY MIX( MIN AND MAX )
第四个例子,我们还可以多次使用聚合函数,比如下面的SQL用来统计公司最低工资和最高工资:
SELECT MIN(FSalary), MAX(FSalary) FROM T_Employee
+--------------+--------------+
| min(FSalary) | MAX(FSalary) |
+--------------+--------------+
| 2300.00 | 8300.00 |
+--------------+--------------+
最后一个介绍的函数就是统计记录数量的COUNT, 这个函数有一点特别,因为它即可以像其他聚合函数一样使用字段名作为参数,也可以使用型号"*"作为参数。执行下面的SQL:
SELECT COUNT(*), COUNT(FNumber) FROM T_Employee
+----------+----------------+
| COUNT(*) | COUNT(FNumber) |
+----------+----------------+
| 7 | 7 |
+----------+----------------+
可以看到COUNT(*) 、COUNT(FNumber)两种方式都能统计出记录的条数,不少开发人云都认为COUNT(*)、COUNT(字段名)这两种使用方式是等价的。下面通过例子来说明,为了看到两种使用方式的区别,首先需要向表T_Employee中插入一条新数据。执行下面的SQL:
INSERT INTO T_Employee(FNumber, FAge, FSalary) VALUES('IT002', 27, 2800)
* 这句INSERT 语句没有为FName字段复制,也就是说新插入的这条数据的FName字段为空。
可以看到FNumber值为IT002行的FName字段是控制。接着下面的SQL:
SELECT COUNT(*), COUNT(FNumber), COUNT(FName) FROM T_Employee
可以看到COUNT(*)、COUNT(FNumber)两个表达式的计算结果都是9,而COUNT(FName)的计算结果是8。这也就反映出了两种使用方式的区别:
COUNT(*)统计的是结果集的总条数,
COUNT(FName)统计的是除了结果接中FName不为空值(也就是不等于NULL)的记录的总条数。
由于FNumber值为IT002的行的FName字段是空值,所以COUNT(FName)的计算结果是8.
因此在使用聚合函数COUNT的时候一定要区分两种使用方式的区别,以防止出现数据统计错误。
排序
到目前为止,数据检索结果的排列顺序取决于数据库系统所决定的排序机制,这种排序机制可能是由数据的输入顺序决定的,也有可能是按照其他的算法来决定的。
在有的情况下我们需要按照某种排序规则来排列检索结果,比如按照工资从高到低的顺序排列或者按照姓名的字符顺序排列等。SELECT语句允许使用ORDER BY 子句来执行结果集的排序方式。
ORDER BY 子句位于SELECT语句的末尾,它允许指定按照一个列或者多个列进行排序,还可以指定排序方式是升序还是降序。
比如下面的SQL语句演示了按照年龄排序的所有员工信息的列表:
SELECT * FROM T_Employee ORDER BY FAge ASC
对于ORDER BY子句来说,升序是默认的排序方式,所以如果采用升序的话可以不指定排序方式,也就是说“ASC”是可以省略的。比如下面的SQL语句具有和上面的SQL语句等效的执行效果:
SELECT * FROM T_Employee ORDER BY FAge
+----------+-------+------+---------+
| FNumber | FName | FAge | FSalary |
+----------+-------+------+---------+
| HR001 | Jane | 23 | 4300.00 |
| DEV001 | Tom | 25 | 8300.00 |
| HR002 | Tina | 25 | 3300.00 |
| SALES001 | Timmy | 25 | 5300.00 |
| IT002 | NULL | 27 | 2800.00 |
| DEV002 | Jerry | 28 | 2300.00 |
| IT001 | Smith | 28 | 5500.00 |
| SALES002 | Stone | 35 | 8300.00 |
+----------+-------+------+---------+
如果需要按照降序排列,那么只要将ASC替换为DESC即可,其中DESC代表降序。执行下面的SQL语句:
SELECT * FROM T_Employee ORDER BY FAge DESC
+----------+-------+------+---------+
| FNumber | FName | FAge | FSalary |
+----------+-------+------+---------+
| SALES002 | Stone | 35 | 8300.00 |
| DEV002 | Jerry | 28 | 2300.00 |
| IT001 | Smith | 28 | 5500.00 |
| IT002 | NULL | 27 | 2800.00 |
| DEV001 | Tom | 25 | 8300.00 |
| HR002 | Tina | 25 | 3300.00 |
| SALES001 | Timmy | 25 | 5300.00 |
| HR001 | Jane | 23 | 4300.00 |
+----------+-------+------+---------+
上面的检索结果中有年龄先供的记录,这些年龄相同的记录之间的顺序是有数据库系统决定的,但是有时可能需要完成
“按照年龄从大到小排序,如果年龄相同则按照工资从大到小排序”之类的排序功能。这可以通过指定多个排序规则来完成,因为ORDER BY
语句允许指定多个排序列,各个列之间逗号隔开即可。
SELECT * FROM T_Employee ORDER BY FAge DESC, FSalary DESC
+----------+-------+------+---------+
| FNumber | FName | FAge | FSalary |
+----------+-------+------+---------+
| SALES002 | Stone | 35 | 8300.00 |
| IT001 | Smith | 28 | 5500.00 |
| DEV002 | Jerry | 28 | 2300.00 |
| IT002 | NULL | 27 | 2800.00 |
| DEV001 | Tom | 25 | 8300.00 |
| SALES001 | Timmy | 25 | 5300.00 |
| HR002 | Tina | 25 | 3300.00 |
| HR001 | Jane | 23 | 4300.00 |
+----------+-------+------+---------+
优先级:从左到右
Note:
ORDER BY子句完全可以与WHERE 子句一起使用,
唯一需要注意的就是ORDER BY 子句要放到WHERE子句之后
不能颠倒它们的顺序。比如下面是错误的:
select * from t_employee order by FAge DESC where FAge > 25 ;
将order by和where子句的位置颠倒则可以执行通过:
select * from t_employee where FAge > 25 order by FAge DESC;