【问题标题】:Is this a right query? If it is what does it mean这是一个正确的查询吗?如果是什么意思
【发布时间】:2011-10-19 01:17:59
【问题描述】:

我收到了一个询问来解释。谁能给我解释一下:

select j.ip_num from 
jobs j, address a
where j.jobtype='C' and
a.sel_code(+)='H' and 
j.ip_num=a.ip_num and
a.ip_num is null order by a.ip_num

【问题讨论】:

    标签: oracle


    【解决方案1】:

    查询正在加入 2 个表作业和地址。这些表在字段 ip_num 上加入,但您正在查找作业表中存在但地址表中不存在的记录。

    这是一个左外连接。这个查询也可以写

    SELECT j.ip_num 
    FROM jobs j
    LEFT OUTER JOIN address a
        ON j.ip_num=a.ip_num
    WHERE j.jobtype='C' AND
        a.sel_code(+)='H' AND 
        a.ip_num is null 
    ORDER BY a.ip_num
    

    查看视觉图片加入http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html 可能很有用

    【讨论】:

    • 这是一个很好且全面的答案。非常感谢。
    • 地址字段中的 sel_code 需要等于 H。至于 (+) 是不应再使用的旧 OUTER JOIN 语法。这是一个关于它的问题 - stackoverflow.com/questions/430274/…
    • 希望其他讨论它的问题会对您有所帮助。
    • 实际上你的重写会抛出ORA-25156: old style outer join (+) cannot be used with ANSI joins
    【解决方案2】:

    该查询选择没有匹配 ADDRESS 记录或匹配 ADDRESS 记录的 SEL_CODE 不等于“H”的每个 JOB.IP_NUM。

    (+) 是 Oracle 的旧外连接语法。它是 9i 之前的 Oracle 版本中唯一支持的 OUTER JOIN 语法。

    在这个查询中,我们为 EMP 中与部门匹配的每一行获取一行,加上没有员工的 DEPTNO=40 的一行:

    SQL> select d.dname
      2         , e.ename
      3  from dept d
      4       , emp e
      5  where d.deptno = e.deptno(+)
      6  /
    
    DNAME          ENAME
    -------------- ----------
    ACCOUNTING     SCHNEIDER
    ACCOUNTING     BOEHMER
    ACCOUNTING     KISHORE
    RESEARCH       ROBERTSON
    RESEARCH       KULASH
    RESEARCH       GASPAROTTO
    RESEARCH       RIGBY
    RESEARCH       CLARKE
    SALES          HALL
    SALES          CAVE
    SALES          SPENCER
    SALES          BILLINGTON
    SALES          PADFIELD
    SALES          VAN WIJK
    SALES          KESTELYN
    SALES          LIRA
    OPERATIONS     PSMITH
    HOUSEKEEPING   VERREYNNE
    HOUSEKEEPING   FEUERSTEIN
    HOUSEKEEPING   PODER
    HOUSEKEEPING   TRICHLER
    COMMUNICATIONS
    
    22 rows selected.
    
    SQL> 
    

    现在,如果我们像这样在 EMP 表上添加一个额外的过滤器,我们只需为每个部门获取一条记录,因为现在 EMP 中只有一条记录匹配:

    SQL> select d.dname
      2         , e.ename
      3  from dept d
      4       , emp e
      5  where d.deptno = e.deptno(+)
      6  and e.ename(+) = 'CAVE'
      7  /
    
    DNAME          ENAME
    -------------- ----------
    ACCOUNTING
    RESEARCH
    SALES          CAVE
    OPERATIONS
    HOUSEKEEPING
    COMMUNICATIONS
    
    6 rows selected.
    
    SQL> 
    /
    

    要将此查询转换为 ANSI SQL 语法,我们必须这样做:

    SQL> select d.dname
      2         , e.ename
      3  from dept d
      4       left outer join emp e
      5          on ( d.deptno = e.deptno
      6               and e.ename = 'CAVE' )
      7  /
    
    DNAME          ENAME
    -------------- ----------
    ACCOUNTING
    RESEARCH
    SALES          CAVE
    OPERATIONS
    HOUSEKEEPING
    COMMUNICATIONS
    
    6 rows selected.
    
    SQL>
    

    请注意,如果我们不在 JOIN 中包含附加子句,而是将其留在 WHERE 子句中,我们会得到不同的结果:

    SQL> select d.dname
      2         , e.ename
      3  from dept d
      4       left outer join emp e
      5          on ( d.deptno = e.deptno )
      6  where  e.ename = 'CAVE'
      7  /
    
    DNAME          ENAME
    -------------- ----------
    SALES          CAVE
    
    SQL>
    

    这相当于在第二个旧 skool 查询中省略 (+)

    【讨论】:

    • 非常感谢@APC。你太棒了。
    猜你喜欢
    • 1970-01-01
    • 2011-05-26
    • 2011-03-12
    • 1970-01-01
    • 2023-02-14
    • 2013-07-24
    • 1970-01-01
    • 1970-01-01
    • 2012-09-14
    相关资源
    最近更新 更多