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)

时间: 2024-11-05 06:23:51

6、分组查询的相关文章

SQL group 分组查询

1.使用group by进行分组查询  在使用group by关键字时,在select列表中可以指定的项目是有限制的,select语句中仅许以下几项:  被分组的列 为每个分组返回一个值得表达式,例如用一个列名作为参数的聚合函数group by的使用在这只写几个例子吧:例: select courseID,avg(score) as 课程平均成绩 from score group by courseID 例: select studentID as 学员编号,courseID as 内部测试,a

mysql分组查询时,讲多个值合并在一行显示

mysql根据字段进行分组查询时,相同字段的数据,只会显示一个,如果要想让这个字段的所有数据,显示在一行里,可以在查询时用GROUP_CONTAT函数,默认数据合并以逗号,分开

8.4Solr API使用(Result Grouping分组查询)

转载请出自出处:http://eksliang.iteye.com/blog/2169458 一.概述 分组统计查询不同于分组统计(Facet),facet只是简单统计记录数,并不能为每组数据返回实际的数据回来,solr提供的grouping查询能够解决这一问题,也就是说,他除了能分组外,还能把每组数据返回来. 二.语法简介 参考实例一 查询参数如下: q=*:* &group=true &group.field=price 返回结果如下: Solr Grouping参数列表 参数 参数含

7-08分组查询

这是一个用户表,下面查询一个用户的数量: --查询表的用户数量 SELECT COUNT(*) FROM UserInfo 再查询一下有几个男用户和几个女用户: SELECT COUNT(*) FROM UserInfo WHERE gender=1 SELECT COUNT(*) FROM UserInfo WHERE gender =0 这样其实把它们分成了两个组,gender=1是男用户,gender=0是女用户,但是有些复杂的表,可以分n个组, 这样在用这种方式比较麻烦,就可以用分组查询

2016/3/13 七种查询 (普通查询 条件查询 排序查询 模糊查询 统计查询 分组查询 分页查询 )

一句话概括的话,SQL作为结构化查询语言,是标准的关系型数据库通用的标准语言: T-SQL 是在SQL基础上扩展的SQL Server中使用的语言 1,普通查询 #查询Info表中的所有列 select * from Info #查询Info表中的Name和Code列 select Name,Code from Info 2,条件查询 关键字where #查询Info表的左右列 限定范围 列名为p001 select * from Info where 列名="p001" #查询条件之

MySQL时间分组查询

表TESTER 字段:id -- INT    date  -- TIMESTAMP 1.如何按年.月.日分组查询? select DATE_FORMAT(date,'%Y-%m-%d') time, count(*) count from TESTER group by year(date), month(date), day(date); 其中year().month().day()分别是提取date中的年.月.日字段. 2.时间分组查询的效率? 在不建立索引时,我100W行数据进行测试,用

S1/C#语言和数据库技术基础/11-连接查询和分组查询

分组查询 采用分组查询的T-SQL语句如下. SELECT   CourseID,AVG(Score)   AS   课程平均成绩 FROM   Score GROUP   BY   CourseID (1)查询男女学生的人数各是多少 SELECT   COUNT(*)    AS   人数,SSex    FROM   Students GROUP   BY   SSex (2)查询每个年级的总人数 SELECT   COUNT(*)   AS   年级人数,SGrade   FROM   S

[Mysql 查询语句]——分组查询group by

#group by(1) group by的含义:将查询结果按照1个或多个字段进行分组,字段值相同的为一组(2) group by可用于单个字段分组,也可用于多个字段分组 select * from employee; +------+------+--------+------+------+-------------+ | num | d_id | name | age | sex | homeaddr | +------+------+--------+------+------+----

SQLServer 分组查询相邻两条记录的时间差

原文:SQLServer 分组查询相邻两条记录的时间差 首先,我们通过数据库中表的两条记录来引出问题,如下图 以上为一个记录操作记录的表数据.OrderID为自增长列,后面依次为操作类型,操作时间,操作人. 现在的问题是:要求筛选出数据库中从“接收”到“送出”的时间差超过2天的全部记录.即如上图两笔单据中,红色框既是要筛选出的,绿色框为正常过滤的. 为了定位相邻记录,方法为给查询语句的返回记录加个自动编号列放入临时表中,再对临时表进行操作. --1.首先查出表中符合條件的所有信息 select

Hibernate5-投影查询,分组查询,Query的List和Iterate

1.创建项目,项目名称hibernatedemo9,目录结构如图所示 2.在项目中创建lib目录存储jar文件,目录结构如图所示 3.在src目录中创建实体Bean Forum,包名(com.mycompany.demo.bean),如图所示 4.实体Bean Forum的内容如下 package com.mycompany.demo.bean; public class Forum { private int fid; private String name; private int issh