6、分组查询

在之前学过一个count()函数,此函数的功能可以统计出表中的数据量,实际上这个就是一个统计函数,而常用的统计函数有如下几个:

1.count():查询表中的数据记录

1.查询emp表中的总记录

        Sql>select count(*) from emp;

2.avg():求出平均值

2.统计出公司的平均工资

    Sql>select avg(sal) from emp;

3.sum():求和;

3.统计出公司的总工资。

        Sql>Select sum(sal) from emp;

4.max():求出最大值

4.查询出emp表中工资最高的员工

            Sql >Select ename,max(sal) from emp;

5.min():求出最小值

5. 查询出emp表中工资最低的员工

       Sql>Select ename,min(sal) from emp;

6.group by:分组统计

当数据重复的时候分组才有意义,因为一个人也可以一组,而如果想要使用group  by子句完成,此时的SQL语法如下:

Select [distinct] *|分组字段1[别名][.分组字段2[.别名],….]|统计函数

From 表名称 [别名],[表名称[别名,….]]

[where 条件(s)][group by 分组字段1[,分组字段2,…]][order by 排序字段 ASC|DESC[,排序字段ASC|DESC]];

6:按照部门编号分组,求出每个部门的人数,平均工资

Sql>Select deptno,count (empno),AVG(sal) from emp group by deptno;

7.按照职位分组,求出每个职位的最高和最低工资

Sql>Select job,max(sal),min(sal) from emp group by job;

8:统计出领取奖金和不领取奖金的雇员人数及平均工资

Sql>Select comm,count(empno),avg(sal) from emp group by comm;

注意:出现分组后,语法上就有一定的限制,对于分组有以下的限制:

》分组函数可以在没有分组的时候单独使用,可是却不能出现其他的查询字段。

分组函数的单独使用

Select count(empno) from emp;

错误的使用,出现了其他的字符;

Select empno,count(empno) from emp;

如果现在要进行分组的话,则select子句之后,只能出现分组的字段和统计函数,其他的字段不能出现:

正确的做法

Select job,count(empno),avg(sal) from emp group by job;

错误的做法

Select deptno,job,count(empno),AVG(sal) from emp group by job;

 

分组函数允许嵌套,但是嵌套之后的分组函数的查询之中不能再出现任何的字段。

9:按照职位分组,统计平均工资最高的职位

Sql>Select job,avg(sal ) from emp group by job;

10:查询出每个部门的名称、位置、部门的人数、平均工资

*确定所需要的数据表:

dept表:每个部门的名称;

emp表:统计出部门的人数平均工资;

*确定已知的关联字段:emp.deptno=dept.deptno;

首先:将dept表和emp表的数据关联

Sql>Select d.dname,e.empno,e.sal from dept d,emp e where d.deptno=e.deptno;

结果显示:

此时的查询结果中,可以发现dname字段上显示出了重复的数据,按照之前对分组的理解,只要数据重复了,那么就有可能进行分组的查询操作,但是此时与之前的分组不太一样,之前的分组是针对于一张实体表进行的分组(emp dept 都属于实体表),但是对于以上的数据是通过查询结果显示的,所以是一张临时的虚拟表,但是不管是否是实体表还是虚拟表,只要是由重复,那么就直接进行分组。

Select d.dname,count(e.ename),avg(e.sal) from dept d,emp e where d.deptno=e.deptno group by d.dname;

但是这个分组并不合适,因为部门一共有四个部门(因为引入了dept表,dept表存在了四个部门的信息),所以应该通过左右连接改变查询的结果。

Select d.dname,count(e.ename),nvl(avg(e.sal),0) from dept d,emp e where d.deptno=e.deptno(+) group by d.dname;

11:查询出每个部门的编号、名称、位置、部门的人数、平均工资

*确定所需要的数据表:

dept表:每个部门的编号、名称、位置;

emp表:统计出部门的人数平均工资;

*确定已知的关联字段:emp.deptno=dept.deptno;

》将emp和dept表关联查询

Select d.deptno,d.dname,d.loc,e.empno,nvl(e.sal,0) from dept d,emp e where d.deptno=e.deptno(+);

结果显示:

此时存在重复数据,而且这个重复的数据平均在了三列上(deptno,dname,loc),所以在分组上的group by 子句中就可以写上三个字段:

Sql>Select d.deptno,d.dname,d.loc,count(e.empno),avg(nvl(e.sal,0)) from dept d,emp e where d.deptno=e.deptno(+)   group by d.deptno,d.dname,d.loc;

7.having:再次过滤子句

 
SQL语言中where和having有什么区别?
    select ··· from ··· where ···(只能对分组前的属性进行筛选) 
    group by ··· having ···(只能对分组后的每个组的整体属性进行筛选,用聚合函数体现) ···· --不使用group by就默认表的整体为一组

Select [distinct] *|分组字段1[别名][.分组字段2[.别名],….]|统计函数

From 表名称 [别名],[表名称[别名,….]]

[where 条件(s)][group by 分组字段1[,分组字段2,…]]

[having 分组后的过滤条件(可以使用统计函数)]

[order by 排序字段 ASC|DESC[,排序字段ASC|DESC]];

 

12:查询部门详细信息按部门名、号和部门位置进行分组且部门的平均工资大于2000;

Sql>Select d.deptno,d.dname,d.loc,count(e.empno),avg(nvl(e.sal,0)) from dept d,emp e where d.deptno=e.deptno(+) group by d.deptno,d.dname,d.loc having avg(sal)>2000;

 

注意:where和having的区别

where:是在执行group by 操作之前进行的过滤,表示从全部数据之中筛选出部分的数据,在where之中不能使用统计函数;

having:是在group by 分组之后的再次过滤,可以在having子句中使用统计函数;

13:显示非销售人员工作名称以及从事同一工作雇员的月工资的总和,并且要满足从事同一工作的雇员的月工资合计大于¥5000,输出结果按月工资的合计升序排列;

Sql>Select  job ,sum(SAL)  from emp where job <> ‘SALESMAN’   group  by job  having sum(SAL)>=5000;

 

 

8、Oracle 删除重复数据只留一条
查询及删除重复记录的SQL语句
 
1、查找表中多余的重复记录,重复记录是根据单个字段(Id)来判断
 

select * from 表 where Id in (select Id from 表 group byId having count(Id) > 1)

 
2、删除表中多余的重复记录,重复记录是根据单个字段(Id)来判断,只留有rowid最小的记录
 

DELETE from 表 WHERE (id) IN ( SELECT id FROM 表 GROUP BY id HAVING COUNT(id) > 1) AND ROWID NOT IN (SELECT MIN(ROWID) FROM 表 GROUP BY id HAVING COUNT(*) > 1);

 
3、查找表中多余的重复记录(多个字段)
 

select * from 表 a where (a.Id,a.seq) in(select Id,seq from 表 group by Id,seq having count(*) > 1)

 
4、删除表中多余的重复记录(多个字段),只留有rowid最小的记录
 

delete from 表 a where (a.Id,a.seq) in (select Id,seq from 表 group by Id,seq having count(*) > 1) and rowid not in (select min(rowid) from 表 group by Id,seq having count(*)>1)

 
5、查找表中多余的重复记录(多个字段),不包含rowid最小的记录
 
select * from 表 a where (a.Id,a.seq) in (select Id,seq from 表 group by Id,seq having count(*) > 1) and rowid not in (select min(rowid) from 表 group by Id,seq having count(*)>1)
原文地址:https://www.cnblogs.com/quyong/p/6688224.html