以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即使最后结果。

解决方案 »

  1.   

    SELECT * FROM emp e WHERE EXISTS (SELECT 1 FROM emp WHERE hiredate <to_date('1981-2-20','yyyy-mm-dd') AND deptno = e.deptno);这是一个相关子查询
    对于外层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,因此外层查询的这条记录就被选中了
      

  2.   

    简单地说,如果exists后子查询中如果有记录行匹配,则相应的exists查询条件就为真。
      

  3.   

    exists后子查询中如果有记录行匹配,则相应的exists查询条件就为真,此条记录就被显示。教科书上都是这么写的。但是让我十分不解的是内层的hiredate <to_date('1981-2-20','yyyy-mm-dd')与deptno = e.deptno是并列关系,必须同时为真,此外层记录才可以显示,为什么结果却是或者关系呢?即与SQL1的结果集一样。
      

  4.   

    内层的两个条件hiredate <to_date('1981-2-20','yyyy-mm-dd') AND deptno = e.deptno
    其实和另外一种写法是一致的
    只不过那种写法只有一层SELECT,而第三种写法有两层SELECT,必须通过deptno = e.deptno条件把两个SELECT来关联起来
      

  5.   

    从父查询中抽取一条记录AAA,并从记录中抽取出deptno,假设值为:100
    把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
      

  6.   

    第一句中的or前面的条件没有用吧
    第二句会有重复记录的,而且等号后面查出多条记录的话会报错的。
    第三句
    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号之前入职的员工称之为老员工
         有老员工的部门称之为老部门
    整句的意思就是列出所有老部门的所有员工过程是:遍历员工表
        找到第一个员工,看他们部门中有没有老员工(这一句就是那个子查询),如果有,就把这个员工留下,没有的话就把这个员工过滤掉。
        以此类推,第二个员工,第三个员工
      

  7.   

    按你这么说 一句
    SELECT * FROM emp WHERE hiredate <to_date('1981-2-20','yyyy-mm-dd')
    完全可以实现了?何必又加那么多其他的东西呢?