以scott用户登录oracle---1
SELECT *
FROM emp
WHERE hiredate <to_date('1981-2-20','yyyy-mm-dd')
OR deptno IN (SELECT deptno FROM emp WHERE hiredate <to_date('1981-2-20','yyyy-mm-dd'));
---2
WITH e AS
(
SELECT * FROM emp e WHERE hiredate <to_date('1981-2-20','yyyy-mm-dd')
)
SELECT * FROM e
UNION
SELECT * FROM emp WHERE deptno = (SELECT deptno FROM e);
---3
SELECT * FROM emp e WHERE EXISTS (SELECT 1 FROM emp WHERE hiredate <to_date('1981-2-20','yyyy-mm-dd') AND deptno = e.deptno);以上3段sql的执行结果是基本相同的,但是我不理解第3种方法,即使用EXISTS 关键字的执行过程。
如:第1种方法执行过程如下
1、SELECT deptno FROM emp WHERE hiredate <to_date('1981-2-20','yyyy-mm-dd')获得结果集A
2、SELECT deptno FROM emp WHERE hiredate <to_date('1981-2-20','yyyy-mm-dd') 获得结果集B
3、SELECT deptno FROM emp WHERE deptno IN A获得结果集C
4、B+C即使最后结果。
SELECT *
FROM emp
WHERE hiredate <to_date('1981-2-20','yyyy-mm-dd')
OR deptno IN (SELECT deptno FROM emp WHERE hiredate <to_date('1981-2-20','yyyy-mm-dd'));
---2
WITH e AS
(
SELECT * FROM emp e WHERE hiredate <to_date('1981-2-20','yyyy-mm-dd')
)
SELECT * FROM e
UNION
SELECT * FROM emp WHERE deptno = (SELECT deptno FROM e);
---3
SELECT * FROM emp e WHERE EXISTS (SELECT 1 FROM emp WHERE hiredate <to_date('1981-2-20','yyyy-mm-dd') AND deptno = e.deptno);以上3段sql的执行结果是基本相同的,但是我不理解第3种方法,即使用EXISTS 关键字的执行过程。
如:第1种方法执行过程如下
1、SELECT deptno FROM emp WHERE hiredate <to_date('1981-2-20','yyyy-mm-dd')获得结果集A
2、SELECT deptno FROM emp WHERE hiredate <to_date('1981-2-20','yyyy-mm-dd') 获得结果集B
3、SELECT deptno FROM emp WHERE deptno IN A获得结果集C
4、B+C即使最后结果。
解决方案 »
- oracle月份分解求解。
- RAC集群连接问题!!!!!急急急!!!!!!!!11
- 如何获得用户能访问的所有表,包括授权访问的其他用户的表
- Linux下自动备份Oracle数据库问题
- oracle 分布式处理的问题
- 为什么oralce不提倡使用in或者or来查询啊?????
- 如何对plsql中的程序加密,这种加密方法plsql5本身有这功能吗?看别人的加密程序,有时看的到一些代码,但一晃而过
- oracle817不能装在p4的计算机上吗?
- 电商用什么数据比较好
- 请问可以将oracle的启动时间控制在10秒以内吗?
- select partition 的困惑,谢谢。
- Xp下oracle11g客户端配置的问题
对于外层SELECT查询从emp表中取出一条记录 和内层SELECT的记录进行匹配
因为在内层限制了条件 hiredate <to_date('1981-2-20','yyyy-mm-dd')
因此,只要外层查询的某条记录和内层查询的某条记录通过条件 deptno = e.deptno匹配上了,就说明外层查询的这条记录符合条件 hiredate <to_date('1981-2-20','yyyy-mm-dd') 。
这时,EXISTS返回1,因此外层查询的这条记录就被选中了
其实和另外一种写法是一致的
只不过那种写法只有一层SELECT,而第三种写法有两层SELECT,必须通过deptno = e.deptno条件把两个SELECT来关联起来
把deptno放到子查询中
假如子查询中存在deptno = 100 且hiredate <to_date('1981-2-20','yyyy-mm-dd')的记录
那么返回exists返回true,在父查询中,记录AAA作为最终结果集的一个元组
在父查询中继续检查下一条记录BBB假如子查询中不存在deptno = 100 且hiredate <to_date('1981-2-20','yyyy-mm-dd')的记录
那么把元组AAA筛选掉,在父查询中继续检查下一条记录BBB
第二句会有重复记录的,而且等号后面查出多条记录的话会报错的。
第三句
SELECT * FROM emp e WHERE EXISTS (SELECT 1 FROM emp WHERE hiredate <to_date('1981-2-20','yyyy-mm-dd') AND deptno = e.deptno);
翻译成汉语可以这样说:
设定 1981年2月20号之前入职的员工称之为老员工
有老员工的部门称之为老部门
整句的意思就是列出所有老部门的所有员工过程是:遍历员工表
找到第一个员工,看他们部门中有没有老员工(这一句就是那个子查询),如果有,就把这个员工留下,没有的话就把这个员工过滤掉。
以此类推,第二个员工,第三个员工
SELECT * FROM emp WHERE hiredate <to_date('1981-2-20','yyyy-mm-dd')
完全可以实现了?何必又加那么多其他的东西呢?