美河学习在线 www.eimhe.com
Oracle 高级 SQL 培训与讲解
美河学习在线 www.eimhe.com
李康康 liakngkang@126.com QQ:353730289
1 With 子句
1.1 学习目标
掌握 with 子句用法,并且了解 with 子句能够提高查询效率的原因。
1.2 With 子句要点
1. with子句的返回结果存到用户的临时表空间中,只做一次查询,反复使用,提高效率。
2. 如果定义了with子句,而在查询中不使用,那么会报ora-32035 错误:未引用在with子
句中定义的查询名。
3. 前面的with子句定义的查询在后面的with子句中可以使用。但是一个with子句内部不能
嵌套with子句。
4. 当一个查询块名字和一个表名或其他的对象相同时,解析器从内向外搜索,优先使用子
查询块名字。
5. with 查询的结果列有别名,引用的时候必须使用别名或*。
6. with 有可能影响执行计划。
1.3 with 子句语法
With alias_name as (select1), --as和select中的括号都不能省略
alias_name2 as (select2),--后面的没有with,逗号分割,同一个主查询同级别地方,with子
查询只能定义一次
…
alias_namen as (select n) –与下面的实际查询之间没有逗号
Select ….
1.4 with 使用例子:
1. 最简单的使用方法:
如查询部门名称包含“A”的所有员工信息
美河学习在线 www.eimhe.com
--with clause
with a as
(select deptno from dept where dname like '%A%')
select * from emp where deptno in (select * from a);
with a as
(select deptno from dept where dname like '%A%'),--a
结果集
a2 as(select * from a where deptno>20)--a1
结果集直接从
a
中筛选
select * from emp where deptno in (select * from a2);
2. 多层同级只能用一个with,并且后面的结果集可以使用前面的结果集:
查询部门名称包含“A”并且部门编号大于20的所有员工信息
with a as
(select deptno from dept where dname like '%A%'),--a
结果集
a2 as(select * from a where deptno>20)--a1
结果集直接从
a
中筛选
select * from emp where deptno in (select * from a2);
3. 不同级查询可以使用多个with:
查询部门名称包含“A”并且部门编号大于20的所有员工信息的另外一种实现方式如下
with a as
(select deptno from dept where dname like '%A%')--a
结果集
select * from emp where deptno in (--
括号内层作为子查询,为第二级
with a2 as(select * from a where deptno>20)--a1
结果集直接从
a
中筛选
select * from a2
);
1.5 使用场景
那什么情况下能使用到 with 子句呢?以下我就举几个简单的例子,简单的说明以下:
1. 我想测试一句 sql,而我不想专门建立一个测试表:
我想测试成绩大于 90 的学生,我不想建立学生表,可以用到 with 子句
with stu as(
select '张娜' sname,99 score from dual union
select '王杰' ,35 from dual union
select '宋丽' ,85 from dual union
select '陈晓' ,73 from dual union
select '李元' ,100 from dual
)--with
组成一个临时的结果集,存放在用户的临时表空间
select * from stu where score>90
2. 当一个 sql 重复用到某个相同的结果集作为子查询:
--
查询销售部工资
>1500
或者销售部工资小于
1000
的员工
select * from emp where deptno=(select deptno from dept where dname
='SALES') and sal >1500
union all
select * from emp where deptno=(select deptno from dept where dname
美河学习在线 www.eimhe.com
='SALES') and sal <1000
--
以上
sql select deptno from dept where dname ='SALES'
需要执行两次,影响效
率
--
可以使用
with
优化一下
with salno as(select deptno from dept where dname ='SALES')
select * from emp where deptno=(select * from salno) and sal >1500
union all
select * from emp where deptno=(select * from salno) and sal <1000
2 集合操作
2.1 学习目标
掌握union,union all,minus,intersect的使用,能够描述集合运算,了解内部运行
原理。
2.2 要点
Union all 效率一般比union高。Union all内部不做排序工作,也不做剔除
重复行工作,而union则做这个工作。所以当数据量比较大的时候,能用union all
的时候尽量用union all。除了union all 默认不做排序和剔除重复行的操作外,
union,minus,intersect都默认按第1个查询结果的第1列进行升序排列,并且
不包含重复行。
2.3 语法
(select resource 1)
Union/union all/minus/intersect
(select resource 2)
美河学习在线 www.eimhe.com
Union/union all/minus/intersect
(select resource 3)
……….
其中查询结果集的各个字段的类型能够互相兼容,并且总的结果集字段名与第一个结果集相
同。
2.4 使用案例
数据准备:
create table t1 as select rownum rn from dual connect by rownum<7;
create table t2 as select rownum+3 rn from dual connect by rownum<7;
1. 查询 t1 和 t2 表的所有记录,不去除重复。
2. 查询 t1 和 t2 表的所有记录,去除重复。