Oracle SQL 条件联接

4

我有以下的SQL语句:

select
    DOCUMENT.DOCUMENT_ID,
    (case
        when DOCUMENT.CLASSIFICATION_CODE is not null
        then DOCUMENT.CLASSIFICATION_CODE
        else TEMPLATE.CLASSIFICATION_CODE end) CLASSIFICATION_CODE,
    CLASSIFICATION.NAME CLASSIFICATION_NAME
from
    DOCUMENT,
    TEMPLATE,
    CLASSIFICATION
where
    DOCUMENT.TEMPLATE_ID = TEMPLATE.TEMPLATE_ID and
    DOCUMENT.CLASSIFICATION_CODE = CLASSIFICATION.CLASSIFICATION_CODE(+)

What I would like to do is along the lines of:

if DOCUMENT.CLASSIFICATION_CODE IS NOT NULL THEN 
  DOCUMENT.CLASSIFICATION_CODE = CLASSIFICATION.CLASSIFICATION_CODE(+),
ELSE
  TEMPLATE.CLASSIFICATION_CODE = CLASSIFICATION.CLASSIFICATION_CODE(+)

可以的吗?

学习使用正确的显式JOIN语法。谁能记得在WHERE子句中(+)的含义? - Gordon Linoff
2
啊!非 ANSI 外连接语法?在2016年!?!?这个世界怎么了! - ErikE
3个回答

4

你可以使用NVL或更常用的COALESCE来实现这个功能:

COALESCE(DOCUMENT.CLASSIFICATION_CODE, TEMPLATE.CLASSIFICATION_CODE)
      = CLASSIFICATION.CLASSIFICATION_CODE(+)

按ANSI语法:

select
    DOCUMENT.DOCUMENT_ID,
    COALESCE(DOCUMENT.CLASSIFICATION_CODE, TEMPLATE.CLASSIFICATION_CODE) 
        CLASSIFICATION_CODE,
    CLASSIFICATION.NAME CLASSIFICATION_NAME
from
    DOCUMENT
inner join 
    TEMPLATE on DOCUMENT.TEMPLATE_ID = TEMPLATE.TEMPLATE_ID
left join
    CLASSIFICATION on
         COALESCE(DOCUMENT.CLASSIFICATION_CODE, TEMPLATE.CLASSIFICATION_CODE) 
       = CLASSIFICATION.CLASSIFICATION_CODE

2

虽然其他答案建议使用coalescenvl,但我更喜欢两次连接classification表。是的,引擎必须执行额外的连接,但避免使用函数使引擎可以使用索引。

SELECT document.document_id,
       COALESCE (d.classification_code, t.classification_code)
          AS classification_code,
       COALESCE (d_c.name, t_c.name) AS classification_name
FROM   document d
       JOIN template t ON d.template_id = t.template_id
       LEFT JOIN classification d_c
          ON d.classification_code = d_c.classification_code
       LEFT JOIN classification t_c
          ON t.classification_code = t_c.classification_code

1
您可以使用以下方法之一:
  • NVL( DOCUMENT.CLASSIFICATION_CODE, TEMPLATE.CLASSIFICATION_CODE )
  • COALESCE( DOCUMENT.CLASSIFICATION_CODE, TEMPLATE.CLASSIFICATION_CODE )
  • 或者 CASE WHEN DOCUMENT.CLASSIFICATION_CODE IS NOT NULL THEN DOCUMENT.CLASSIFICATION_CODE ELSE TEMPLATE.CLASSIFICATION_CODE END (与您在SELECT子句中使用的方式完全相同)

作为连接条件,如下所示:

SELECT d.DOCUMENT_ID,
       NVL( d.CLASSIFICATION_CODE, t.CLASSIFICATION_CODE )
         AS CLASSIFICATION_CODE,
       c.NAME AS CLASSIFICATION_NAME
FROM   DOCUMENT d
       INNER JOIN TEMPLATE t
       ON ( d.TEMPLATE_ID = t.TEMPLATE_ID )
       LEFT OUTER JOIN CLASSIFICATION c
       ON ( NVL( d.CLASSIFICATION_CODE, t.CLASSIFICATION_CODE )
              = c.CLASSIFICATION_CODE )

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接