【问题标题】:Oracle SQL conditional joinOracle SQL 条件连接
【发布时间】:2016-04-25 18:07:54
【问题描述】:

我有以下 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(+)

我想做的是:

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

这可能吗?

【问题讨论】:

  • 学习使用正确的显式JOIN 语法。谁能记住(+)WHERE 子句中的含义?
  • 哎呀!非ANSI外连接语法? 2016年!?!?!这个世界会变成什么样子!

标签: sql oracle join


【解决方案1】:

您可以为此使用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
    

    【讨论】:

      【解决方案3】:

      你可以使用:

      • 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 )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-07-28
        • 1970-01-01
        • 1970-01-01
        • 2012-08-16
        • 1970-01-01
        • 2022-07-19
        • 1970-01-01
        相关资源
        最近更新 更多