数据汇总

 

有时需要对数据库中的数据进行一些统计,比如统计员工总数,统计年龄大于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;