2014-03-28 79 views
0

我想将查询从THERAPY表中链接到我的查找表REF_CODE;字段PROT(可以为空)和字段THER_TYPE(非空)。 REF_CODE包含多个查找类别,由CAT_ID进行区分。我此刻的查询看起来是这样的:SQL查询 - 一次查询两个字段的链接

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'; 

有两种治疗记录,其中EVENT_ID = 1234这个查询只返回记录,其中PROT不为空。 PROT = null的记录完全不会返回。

这是为什么?无论PROT是否为空,我如何返回所有值?

+0

您使用的是什么版本的SQL? – Abraham

+0

可能重复的[左外连接不工作?](http://stackoverflow.com/questions/12467744/left-outer-join-not-working) – Abraham

+0

使用Oracle 11g的方式.... – davemere

回答

1

试试这个..

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; 

以下是我对你的代码进行更改:

  1. 你在你的第二JOIN做一个INNER JOINREF_CODE因此NULL值会降低结果。我把它改成一个LEFT JOIN

  2. 你的第二个问题归结为您filter criteriaONWHERE条款的位置。

第二点说明:

INNER JOIN,您可以使用ONWHERE interchangebly。基础逻辑不会改变,也不会影响执行计划。

它与OUTER JOINs完全不同。正如你可以看到你的情况,一个错位的过滤器可以完全歪曲逻辑。

a。 Filter Criteria in the WHERE Clause

SELECT * FROM A left join B 
ON A.id=B.id 
WHERE B.id=1 

上面的查询将起作用像INNER JOIN和整个结果仅限制与B.id=1行(注意,所述过滤器被应用到表上LEFT JOIN操作者的右侧)

Filter Criteria in the ON Clause

SELECT * FROM A left join B 
ON A.id=B.id 
AND B.id=1 

上面的查询,因为它们被映射到table ALEFT JOIN操作者将只限制table B的行。所以结果将包含table B列所有行的table A和值仅适用于符合B.id=1

+0

感谢SoulTrain。 ..但我恐怕这仍然不会带回PROT = null的记录。不知道我在这里错过了什么......! – davemere

+0

我想我知道是什么导致你的情况。你可以尝试更新的代码,看看它是否工作。我会解释这些变化,如果有效的话。 – SoulTrain

+0

您的Where子句限制了结果集。检查更新的代码。 – SoulTrain

1

我创建了一个SQL Fiddle查询,以测试你的问题的条件的行。请检查以确认它符合您的方案。

where子句正在争夺左连接。将两个过滤器上CAT_ID到加盟条款是这样的:

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; 

其他不干净的方式做,这就是围绕与左侧的where子句的部分与isnull()这样加入:

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' 

看到这个相似的答案Left Outer Join Not Working

附加:

如果@ SoulTrain的查询工作,那么你一定也有在Ref_Code做不匹配排在疗法行。在这种情况下,您确实需要使用两个左连接,但连接的顺序并不重要。请参阅updated SQL Fiddle Example以查看此查询的实际操作。这是最后一个查询。

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; 
+0

嗨亚伯拉罕。第一个例子不起作用 - 仍然排除PROT = null的记录。我错过了什么? – davemere

+0

这个答案是否有帮助http://stackoverflow.com/a/11096237/269123?他似乎做的唯一不同的是他在连接子句中使用括号。让我知道这是否有帮助,我会更新答案。 – Abraham

+0

我看不出为什么这个声明不应该得到想要的记录。将条件移至on子句可解决问题。在这里加入订单并不重要。从r1到r2没有关系。 davemere,你的问题在别的地方。当你从查询中删除r2时,你会得到记录吗?或者在删除r1时获得它们?检查这一点,并考虑你的查询。 –