我有一个使用左外连接构造的查询,如下所示:
left outer JOIN GA_LOAN GA
ON LOAN.LOAN_TYPE = GA.LOAN_TYP
AND LOAN.DT = GA.GUARANTY_DT
AND LOAN.FFEL_DUP_ID = GA.SEP_LOAN_IND
AND LOAN.SCH_BR_CODE = GA.ORIG_SCHL_CD
AND STU.CURR_SSN = GA.STU_SSN
AND STU.DOB = GA.DOB
and stu.curr_fst = ga.stu_first_nam
--and (plus_bor.curr_ssn is not distinct from ga.plus_brwr_ssn )
当我添加注释掉的行时,我收到以下错误。
ORA-00908: missing NULL keyword
00908. 00000 - "missing NULL keyword"
*Cause:
*Action:
与DB2中此结构中的正常工作没有区别,但Oracle给了我一些问题。有什么建议吗?
如果我将is not distinct from
替换为=
,但逻辑上不一样,我就没有错误。
is not distinct from
,那么 null
会给出匹配,而=
在这种情况下不匹配。
答案 0 :(得分:0)
您可以使用IS DISTINCT FROM
结合NOT EXISTS
来模仿INTERSECT
:
plus_bor.curr_ssn IS DISTINCT FROM ga.plus_brwr_ssn
<=>
NOT EXISTS (SELECT plus_bor.curr_ssn FROM dual INTERSECT
SELECT ga.plus_brwr_ssn FROM dual);
示例:
WITH cte(a,b) AS (
SELECT 1, NULL FROM dual UNION ALL
SELECT 1,2 FROM dual UNION ALL
SELECT 1,1 FROM dual UNION ALL
SELECT NULL, 1 FROM dual UNION ALL
SELECT NULL, NULL FROM dual
)
SELECT *
FROM cte
WHERE NOT EXISTS (SELECT a FROM dual INTERSECT
SELECT b FROM dual)
<强> Rextester Demo 强>
输出:
A B
------------
1 NULL
1 2
NULL 1
在您的情况下,IS NOT DISTINCT FROM
只是EXISTS
:
plus_bor.curr_ssn IS NOT DISTINCT FROM ga.plus_brwr_ssn
<=>
EXISTS (SELECT plus_bor.curr_ssn FROM dual INTERSECT
SELECT ga.plus_brwr_ssn FROM dual);
示例:
WITH cte(a,b) AS (
SELECT 1, NULL FROM dual UNION ALL
SELECT 1,2 FROM dual UNION ALL
SELECT 1,1 FROM dual UNION ALL
SELECT NULL, 1 FROM dual UNION ALL
SELECT NULL, NULL FROM dual
)
SELECT *
FROM cte
WHERE EXISTS (SELECT a FROM dual INTERSECT
SELECT b FROM dual);
输出:
A B
1 1
NULL NULL
<强> Rextester Demo2 强>
与评论中提出的COALESCE/NVL
方法相比,这种方法有一个很大的优势。
您不必考虑依赖于数据类型的默认中性值。
例如,如果列是数据类型DATE
/ INT
/ TEXT
,那么您必须编写如下内容:
coalesce(col1,DATE '1900-01-01') = coalesce(col2,DATE '1900-01-01')
coalesce(col1, 0) = coalesce(col2, 0)
coalesce(col1, ' ') = coalesce(col2, ' ')
当然有轻微的碰撞机会。例如:
coalesce(col1, 0) = coalesce(col2, 0)
=>
col1 = NULL
col2 = 0
and we have incorrect match!!!
答案 1 :(得分:0)
在 Oracle 中模拟 IS [ NOT ] DISTINCT FROM
的最简单方法是使用 DECODE
:
-- a IS DISTINCT FROM b
DECODE(a, b, 1, 0) = 0
-- a IS NOT DISTINCT FROM b
DECODE(a, b, 1, 0) = 1
这就是您在使用 jOOQ's SQL dialect translator 时得到的结果。一个 dbfiddle:
WITH t (x) AS (
SELECT 1 FROM dual UNION ALL
SELECT 2 FROM dual UNION ALL
SELECT null FROM dual
)
SELECT
t1.x AS x1,
t2.x AS x2,
DECODE(t1.x, t2.x, 1, 0) AS not_distinct
FROM t t1, t t2
ORDER BY 1, 2
产量:
X1 | X2 | NOT_DISTINCT
-----+------+-------------
1 | 1 | 1
1 | 2 | 0
1 | null | 0
2 | 1 | 0
2 | 2 | 1
2 | null | 0
null | 1 | 0
null | 2 | 0
null | null | 1