SQL查询-链接到同时具有两个字段的查找
我想组合一个查询,将治疗表中的两个字段链接到我的查找表REF_代码;字段保护(可以为空)和字段类型(非空)。REF_代码包含多个查找类别,以CAT_ID区分。我目前的查询如下:SQL查询-链接到同时具有两个字段的查找,sql,oracle11g,Sql,Oracle11g,我想组合一个查询,将治疗表中的两个字段链接到我的查找表REF_代码;字段保护(可以为空)和字段类型(非空)。REF_代码包含多个查找类别,以CAT_ID区分。我目前的查询如下: SELECT THER_ID, r1.CODE_NAME, r2.CODE_NAME FROM THER t LEFT JOIN REF_CODE r1 ON t.PROT = r1.CODE JOIN REF_CODE r2 ON t.THER_TYPE = r2.CODE WHERE EVENT_ID = 1234
SELECT THER_ID, r1.CODE_NAME, r2.CODE_NAME
FROM THER t
LEFT JOIN REF_CODE r1 ON t.PROT = r1.CODE
JOIN REF_CODE r2 ON t.THER_TYPE = r2.CODE
WHERE EVENT_ID = 1234
AND r1.CAT_ID = '1'
AND r2.CAT_ID = '2';
SELECT THER_ID, r1.CODE_NAME, r2.CODE_NAME as Name2
FROM THER t
LEFT JOIN REF_CODE r1 ON t.PROT = r1.CODE AND r1.CAT_ID = '1'
JOIN REF_CODE r2 ON t.THER_TYPE = r2.CODE AND r2.CAT_ID = '2'
WHERE EVENT_ID = 1234;
SELECT THER_ID, r1.CODE_NAME, r2.CODE_NAME as Name2
FROM THER t
LEFT JOIN REF_CODE r1 ON t.PROT = r1.CODE
JOIN REF_CODE r2 ON t.THER_TYPE = r2.CODE AND r2.CAT_ID = '2'
WHERE EVENT_ID = 1234
AND Coalesce(RTRIM(r1.CAT_ID),'1') = '1'
有两个治疗记录,其中EVENT_ID=1234。此查询仅返回PROT不为null的记录。PROT=null的记录根本不会返回
为什么会这样?无论PROT是否为null,如何返回所有值?试试这个
SELECT THER_ID, r1.CODE_NAME, r2.CODE_NAME
FROM THER t
LEFT JOIN REF_CODE r1 ON t.PROT = r1.CODE
and r1.CAT_ID = '1'
LEFT JOIN REF_CODE r2 ON t.THER_TYPE = r2.CODE
AND r2.CAT_ID = '2'
WHERE EVENT_ID = 1234;
以下是我对您的代码所做的更改:
REF\u code
在第二次连接中执行内部连接
,因此NULL
值将从结果中删除。我把它改成了左连接筛选条件
在ON
和WHERE
子句中的位置内部联接中
,可以互换使用上的和中的。底层逻辑不会改变,也不会对执行计划产生影响
对于外部联接
,情况完全不同。正如您在案例中所看到的,错误放置的过滤器可能会完全扭曲逻辑
a<代码>WHERE子句中的筛选条件
SELECT * FROM A left join B
ON A.id=B.id
WHERE B.id=1
SELECT * FROM A left join B
ON A.id=B.id
AND B.id=1
上述查询的功能类似于内部联接
,并将整个结果仅限于B.id=1
的行(请注意,过滤器应用于左联接
运算符右侧的表)
b<代码>ON子句中的筛选条件
SELECT * FROM A left join B
ON A.id=B.id
WHERE B.id=1
SELECT * FROM A left join B
ON A.id=B.id
AND B.id=1
上面的查询只会限制表B
的行,因为它们在左联接
操作符中映射到表A
。因此,结果将包含表A
的所有行,以及表B
列中的值,仅包含与条件B.id=1
匹配的行。我创建了一个查询来测试您的问题。请检查以验证它是否符合您的场景
where子句胜过了左连接。将Cat_ID上的两个筛选器移动到join子句中,如下所示:
SELECT THER_ID, r1.CODE_NAME, r2.CODE_NAME
FROM THER t
LEFT JOIN REF_CODE r1 ON t.PROT = r1.CODE
JOIN REF_CODE r2 ON t.THER_TYPE = r2.CODE
WHERE EVENT_ID = 1234
AND r1.CAT_ID = '1'
AND r2.CAT_ID = '2';
SELECT THER_ID, r1.CODE_NAME, r2.CODE_NAME as Name2
FROM THER t
LEFT JOIN REF_CODE r1 ON t.PROT = r1.CODE AND r1.CAT_ID = '1'
JOIN REF_CODE r2 ON t.THER_TYPE = r2.CODE AND r2.CAT_ID = '2'
WHERE EVENT_ID = 1234;
SELECT THER_ID, r1.CODE_NAME, r2.CODE_NAME as Name2
FROM THER t
LEFT JOIN REF_CODE r1 ON t.PROT = r1.CODE
JOIN REF_CODE r2 ON t.THER_TYPE = r2.CODE AND r2.CAT_ID = '2'
WHERE EVENT_ID = 1234
AND Coalesce(RTRIM(r1.CAT_ID),'1') = '1'
另一种不太干净的方法是用isnull()
将where子句中与左连接相关的部分包围起来,如下所示:
SELECT THER_ID, r1.CODE_NAME, r2.CODE_NAME
FROM THER t
LEFT JOIN REF_CODE r1 ON t.PROT = r1.CODE
JOIN REF_CODE r2 ON t.THER_TYPE = r2.CODE
WHERE EVENT_ID = 1234
AND r1.CAT_ID = '1'
AND r2.CAT_ID = '2';
SELECT THER_ID, r1.CODE_NAME, r2.CODE_NAME as Name2
FROM THER t
LEFT JOIN REF_CODE r1 ON t.PROT = r1.CODE AND r1.CAT_ID = '1'
JOIN REF_CODE r2 ON t.THER_TYPE = r2.CODE AND r2.CAT_ID = '2'
WHERE EVENT_ID = 1234;
SELECT THER_ID, r1.CODE_NAME, r2.CODE_NAME as Name2
FROM THER t
LEFT JOIN REF_CODE r1 ON t.PROT = r1.CODE
JOIN REF_CODE r2 ON t.THER_TYPE = r2.CODE AND r2.CAT_ID = '2'
WHERE EVENT_ID = 1234
AND Coalesce(RTRIM(r1.CAT_ID),'1') = '1'
有关详细信息,请参见此类似答案
其他:
如果@SoulTrain的查询有效,那么您必须在Ther中有与Ref\u Code中的行不匹配的行。在这种情况下,确实需要使用两个左联接,但联接的顺序并不重要。请参阅以查看此查询的操作。这是最后一个查询
SELECT THER_ID, r1.CODE_NAME, r2.CODE_NAME
FROM THER t
LEFT JOIN REF_CODE r1 ON t.PROT = r1.CODE and r1.Cat_ID = 1
LEFT JOIN REF_CODE r2 ON t.THER_TYPE = r2.CODE AND r2.CAT_ID = '2'
WHERE EVENT_ID = 1234;
您使用的是什么版本的SQL?顺便说一句,可能与使用Oracle 11g的版本相同……嗨,亚伯拉罕。不幸的是,第一个示例不起作用-仍然排除PROT=null的记录。我遗漏了什么?这个答案有用吗?唯一不同的是,他在连接子句中使用了括号。让我知道这是否有帮助,我会更新答案。我看不出为什么此语句不能获得所需的记录。将标准移动到on子句可以解决此问题。加入顺序在这里并不重要。r1和r2之间没有关系。达维梅尔,你的问题在别的地方。从查询中删除r2时,您是否获得记录?或者,在删除r1时,您是否获得了这些信息?请检查并仔细考虑您的查询。@davemere-我添加了一个SQLFiddle示例来模拟您描述的场景。请查看链接。我还修改了第二个查询的语法,使用Coalesce而不是ISNULL。这有用吗?@ThorstenKettner谢谢你支持我。数据中一定有其他内容。谢谢SoulTrain…但我担心这仍然无法返回PROT=null的记录。不知道我在这里错过了什么。。。!我想我知道是什么导致了你的情况。你能试试更新后的代码,看看它是否有效吗。如果有效,我将解释更改。您的Where
子句限制了结果集。检查更新的code.SoulTrain,太棒了!这个查询似乎与我非常相似……只是WHERE子句位于不同的位置。你能解释一下为什么会这样吗?当然。。。我稍后会解释。