日期:2014-05-16  浏览次数:20514 次

group by和order by详解

select
u1,sum(u2),u3,sum(u4) -- A位置
from student
group by? u2, u3 -- B位置

A位置中没有出现在B位置的字段必须使用聚集函数,在B位置出现的字段分组,分组的含义就是这些字段都相等的合并为一条数据。

如上面sql的行已就是:把u2,u3相等的记录合并为一条,u2,u4的值为加总的。


-------------------------------------------------

在select 语句中可以使用group by 子句将行划分成较小的组,然后,使用聚组函数返回每一个组的汇总信息,另外,可以使用having子句返回满足having条件的组。

在带有group by 子句的查询语句中,在select 列表中指定的列要么是group by 子句中指定的列,要么包含聚组函数

select max(sal),job emp group by job;
(注意:select job的job在此处会 显示 按job分组的第一个job字段,无意义)


查询语句的select 和group by ,having 子句是聚组函数唯一出现的地方,在where 子句中不能使用聚组函数。

select deptno,sum(sal) from emp where sal>1200 group by deptno having sum(sal)>8500 order by deptno;

当在gropu by 子句中使用having 子句时,查询结果中只返回满足having条件的组。在一个sql语句中可以有where子句和having子句。having 与where 子句类似,均用于设置限定条件

where 子句的作用是在对查询结果进行分组前,将不符合where条件的行去掉,即在分组之前过滤数据,条件中不能包含聚组函数,使用where条件显示特定的行。
having 子句的作用是筛选满足条件的组,即在分组之后过滤数据,条件中经常包含聚组函数,使用having 条件显示特定的组,也可以使用多个分组标准进行分组。

查询每个部门的每种职位的雇员数(先按deptno分组,在deptno分好的组中再按job分组)
select deptno,job,count(*) from emp group by deptno,job;





/* group by 详解 */

drop table if exists wage;

create table wage(
??? id int not null auto_increment,
??? stafferId int not null,
??? monthId int not null,
??? money double not null,
??? primary key (id)
)
*/

/* 初始化数据 */
-- insert into wage(stafferId,monthId,money) values(1,1,500),(2,1,1000),(3,1,1200),(1,2,1000),(2,2,2000),(3,2,1300),(1,3,1000),(2,3,1500),(3,3,1700);

1??? 1??? 1??? 500
2??? 2??? 1??? 1000
3??? 3??? 1??? 1200
4??? 1??? 2??? 1000
5??? 2??? 2??? 2000
6??? 3??? 2??? 1300
7??? 1??? 3??? 1000
8??? 2??? 3??? 1500
9??? 3??? 3??? 1700




select stafferId as '员工编号',monthId as '月份',money as '工资' from wage
group by monthId

/*
result:
+----------+------+------+
| 员工编号 | 月份 | 工资 |
+----------+------+------+
|??????? 1 |??? 1 |? 500 |
|??????? 1 |??? 2 | 1000 |
|??????? 1 |??? 3 | 1000 |
+----------+------+------+

员工编号、工资 分别是表中1、2、3月份的第一条数据,无意义。应在select或group by中使用聚组函数
*/







/* order by详解 */

select * from wage
order by stafferId ASC, monthId DESC

先按stafferId升序排序,在stafferId一样的分组中(stafferId=1),再进行monthId降序排序

result:
+----+-----------+---------+-------+
| id | stafferId | monthId | money |
+----+-----------+---------+-------+
| 52 |???????? 1 |?????? 3 |? 1000 |
| 49 |???????? 1 |?????? 2 |? 1000 |
| 46 |???????? 1 |?????? 1 |?? 500 |
| 53 |???????? 2 |?????? 3 |? 1500 |
| 50 |???????? 2 |?????? 2 |? 2000 |
| 47 |???????? 2 |?????? 1 |? 1000 |
| 54 |???????? 3 |?????? 3 |? 1700 |
| 51 |???????? 3 |?????? 2 |? 1300 |
| 48 |???????? 3 |?????? 1 |? 1200 |
+----+-----------+---------+-------+