zoukankan      html  css  js  c++  java
  • 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)
  • 相关阅读:
    (感受)新人生的三种境界
    (学)如何在打印时对横向页面重复左端标题
    (原)解决.NET 32位程序运行在64位操作系统下的兼容性问题
    (原)儿子上小学了
    OSG学习过程中的笔记
    从c++角度学习JAVA、Android的总结
    Android Studio利用cmakelists.txt编译OSG的方法总结
    android studio 利用gradle和cmakelist生成c++静态库.a的方法总结
    Android Studio使用c++静态库的方法总结(hello-libs为例)
    Android.mk、CMake、Gradle简介 NDK和JNI的关系
  • 原文地址:https://www.cnblogs.com/quyong/p/6688224.html
Copyright © 2011-2022 走看看