Oracle SQL 条件连接
Posted
技术标签:
【中文标题】Oracle SQL 条件连接【英文标题】:Oracle SQL conditional join 【发布时间】: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年!?!?!这个世界会变成什么样子!
【参考方案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】:虽然您可以使用coalesce
或nvl
,但正如其他答案所建议的那样,我更愿意加入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 )
【讨论】:
以上是关于Oracle SQL 条件连接的主要内容,如果未能解决你的问题,请参考以下文章