一、union
1. union 的处理过程:
union all 是简单的将结果集合并后返回,想必大家都清楚,这里就不举例了。而 union 处理结果集时稍微复杂些,不仅去重,还会排序。union 的处理过程是先取出两个结果集,再用排序空间删除重复记录(所以,不仅仅是去除 union 连接起来的结果集之间的重复数据,而是在整个返回的结果集中去重)。
-- 没用 union 产生重复记录 select emp.deptno from emp;
![]()
-- 和一个空集进行 union 连接,去重 select emp.deptno from emp union select emp.empno from emp where 1 = 2
![]()
上边第二个 sql 中 union 连接了一个有重复记录的结果集和一个空集,最终返回的结果集只有一条记录。所以,union 是在整个结果集中去重。
二、with 语句
1. with语法
with 语句的效果很想临时创建若干个视图(view),在 sql 执行完毕后销毁。with 可以创建多个这样“临时view”,而且创建次序以上之下,后边的可以引用前边已经创建好的“临时view”。
-- with 语法 with e1 as(select emp.* from emp where emp.empsalary >= 3000), e2 as(select emp.* from emp where emp.deptno = 'dept02'), e3 as(select e1.empno, e1.deptno, e1.empsalary from e1, e2 where e1.empno = e2.empno) select * from e3;
![]()
e1 查询工资大于等于 3000 的员工,e2 查询部门在 dept02 的员工,e3 用empno 关联 e1、e2 产生的结果集表示“工资大于等于 3000,在 dept02 部门的所有员工”。在这里,e3 引用了e1 和 e2 两个“临时view”。
三、in 和 exists
1. in 与 exists 的区别:
在子查询中,in 是 把外表和内表做 hash 链接,exists 是把内表和外表做 loop 循环。一直以来都说“exists 比 in 效率高”貌似是不准确的。子查询(内)表大用 exists,子查询表小用 in。
例如:
表A(小表),表B(大表)
表A(大表),表B(小表)select * from A where id in(select id from B) -->效率低,用到了A表上cc列的索引 select * from A where exists(select id from B where A.id = B.id)
exists 和 in 具体效率上的差异还有待验证。select * from B where id in(select id from A) -->效率高,用到了B表上cc列的索引 select * from B where exists(select id from A where A.id = B.id)