http://blog.csdn.net/rosekin/article/details/39298255
此时如果要对分组后的数据再次进行过滤,则使用HAVING子句完成,那么此时的SQL语法格式如下:
SELECT [DISTINCT] *|分组字段1 [别名] [,分组字段2 [别名] ,…] | 统计函数 FROM 表名称 [别名], [表名称 [别名] ,…] [WHERE 条件(s)] [GROUP BY 分组字段1 [,分组字段2 ,…]] [HAVING 分组后的过滤条件(可以使用统计函数)] [ORDER BY 排序字段 ASC | DESC [,排序字段 ASC | DESC]];
下面使用HAVING进行过滤。
SELECT d.deptno,d.dname,d.loc,COUNT(e.empno) mycount,NVL(AVG(e.sal),0) myavg 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子句中使用统计函数;
五、子查询
子查询 = 简单查询 + 限定查询 + 多表查询 + 统计查询的综合体;
在之前强调过多表查询不建议大家使用,因为性能很差,但是多表查询最有利的替代者就是子查询,所以子查询在实际的开发之中使用的相当的多;
所谓的子查询指的就是在一个查询之中嵌套了其他的若干查询,嵌套子查询之后的查询SQL语句如下:
SELECT [DISTINCT] *|分组字段1 [别名] [,分组字段2 [别名] ,…] | 统计函数 ,( SELECT [DISTINCT] *|分组字段1 [别名] [,分组字段2 [别名] ,…] | 统计函数 FROM 表名称 [别名], [表名称 [别名] ,…] [WHERE 条件(s)] [GROUP BY 分组字段1 [,分组字段2 ,…]] [HAVING 分组后的过滤条件(可以使用统计函数)] [ORDER BY 排序字段 ASC | DESC [,排序字段 ASC | DESC]]) FROM 表名称 [别名], [表名称 [别名] ,…] ,( SELECT [DISTINCT] *|分组字段1 [别名] [,分组字段2 [别名] ,…] | 统计函数 FROM 表名称 [别名], [表名称 [别名] ,…] [WHERE 条件(s)] [GROUP BY 分组字段1 [,分组字段2 ,…]] [HAVING 分组后的过滤条件(可以使用统计函数)] [ORDER BY 排序字段 ASC | DESC [,排序字段 ASC | DESC]]) [WHERE 条件(s) ( SELECT [DISTINCT] *|分组字段1 [别名] [,分组字段2 [别名] ,…] | 统计函数 FROM 表名称 [别名], [表名称 [别名] ,…] [WHERE 条件(s)] [GROUP BY 分组字段1 [,分组字段2 ,…]] [HAVING 分组后的过滤条件(可以使用统计函数)] [ORDER BY 排序字段 ASC | DESC [,排序字段 ASC | DESC]])] [GROUP BY 分组字段1 [,分组字段2 ,…]] [HAVING 分组后的过滤条件(可以使用统计函数)] [ORDER BY 排序字段 ASC | DESC [,排序字段 ASC | DESC]];
理论上子查询可以出现在查询语句的任意位置上,但是从个人而言,子查询出现在WHERE和FROM子句之中较多;
以下的使用特点为个人总结,不是官方声明的:
- WHERE:子查询一般只返回单行列、多行单列、单行多列的数据;
- FROM:子查询返回的一般是多行的数据,当作一张临时表出现。
<strong>内连接</strong>
同时显示部门名称和员工信息。Select两个表的写法,内连接。公共匹配的
数据
简化的写法
Dept表,employee表
Select d.name,e.name,sex from employee e,dept d where e.id=d.id
标准的写法:
Select d.name,e.name,sex from employee e join dept d on e.id=d.id
<strong>外连接:</strong>
左连接:
左边员工表的记录全部显示。右边表只显示匹配的,相同的部分显示一次
Select d.name,e.name,sex from employee e,dept d where e.id=d.id(+)
右连接正好相反
左连接和右连接合成为外连接
<strong>子查询</strong>
In写法和下面的exists是一个意思
Select * from employee e where id not in (select id from dept where id=’3’);
Select * from employee e where id in (select id from dept where id=’3’);
Exists写法和上面的in是一个意思,exists可以用*来匹配。
Select * from employee e where not exists (select * from d where id=e.id)
Select * from employee e where exists (select id from d where id=e.id)
union合并行数据,只是显示,不变化物理数据
select id from e
union
select id from d;
相同的行数据合并。不同的只显示一次
<u>将两个表中合并显示。只是显示相同的行数据</u>
Select id from e
Intersect
Select id from d
<strong>用别的表的结果集插入到别的表中</strong>
Insert into e(eid,ename) select id,name from d;
<strong>复制表</strong>
将一行数据放进去表中,把已有表的字段和数据行
放到一个表中用来复制
Create table ttt as select e.id,e.name from e where eid=’001’
同时显示部门名称和员工信息。Select两个表的写法,内连接。公共匹配的
数据
简化的写法
Dept表,employee表
Select d.name,e.name,sex from employee e,dept d where e.id=d.id
标准的写法:
Select d.name,e.name,sex from employee e join dept d on e.id=d.id
<strong>外连接:</strong>
左连接:
左边员工表的记录全部显示。右边表只显示匹配的,相同的部分显示一次
Select d.name,e.name,sex from employee e,dept d where e.id=d.id(+)
右连接正好相反
左连接和右连接合成为外连接
<strong>子查询</strong>
In写法和下面的exists是一个意思
Select * from employee e where id not in (select id from dept where id=’3’);
Select * from employee e where id in (select id from dept where id=’3’);
Exists写法和上面的in是一个意思,exists可以用*来匹配。
Select * from employee e where not exists (select * from d where id=e.id)
Select * from employee e where exists (select id from d where id=e.id)
union合并行数据,只是显示,不变化物理数据
select id from e
union
select id from d;
相同的行数据合并。不同的只显示一次
<u>将两个表中合并显示。只是显示相同的行数据</u>
Select id from e
Intersect
Select id from d
<strong>用别的表的结果集插入到别的表中</strong>
Insert into e(eid,ename) select id,name from d;
<strong>复制表</strong>
将一行数据放进去表中,把已有表的字段和数据行
放到一个表中用来复制
Create table ttt as select e.id,e.name from e where eid=’001’