制定TSQL左连接

时间:2011-10-07 17:38:26

标签: tsql join

我正在使用SSMS 2008.应该是一个简单的解决方案。我试图从表A中提取所有记录,但只从表B和C中提取匹配记录。问题是如果我离开连接表B和C,它将返回所有这3个表相交的记录。就像我查询这个组合合并一样,我为B和C的每一行都得到非NULL值。

这是我的伪代码:

SELECT A.ID, B.ID, C.ID
FROM A
LEFT JOIN B ON B.ID = A.ID
LEFT JOIN C ON C.ID = A.ID

在回答你的问题时,我很抱歉忘记了“左”,但我刚刚在上面添加了它。如果表A有9行而B有2行而C有3行,那么我想看到的是表A与B相交并且A与C相交的地方。 所以在刚刚描述的场景中,假设表B行全部不同于表C行,那么我想看到总共5行; 2来自B,3来自C.有意义吗?

4 个答案:

答案 0 :(得分:1)

执行此操作的理想方法是使用LEFT JOIN。我相信(虽然你的问题不清楚)你遇到的问题是每A.ID多行。

如果A.IDB.ID AND C.ID匹配,那么您将获得两行,并希望合并一行。

我想也许你的JOIN条件在测试查询中混淆了。这在测试中对我来说很好。请尝试以下查询:

DECLARE @A TABLE (ID INT)
DECLARE @B TABLE (ID INT)
DECLARE @C TABLE (ID INT)

INSERT INTO @A VALUES
(1),
(2),
(3),
(4)

INSERT INTO @B VALUES
(2),
(3)

INSERT INTO @C VALUES
(3),
(4)

SELECT A.ID, B.ID, C.ID
FROM @A A
LEFT JOIN @B B
    ON B.ID = A.ID
LEFT JOIN @C C
    ON C.ID = A.ID

输出是:

ID  ID      ID
1   NULL    NULL
2   2       NULL
3   3       3
4   NULL    4

答案 1 :(得分:1)

你想要的是加入一个联合声明。

SELECT A.ID, 
case when D.tablename = 'B' then  ID else null end, 
case when D.tablename = 'C' then  ID else null end
FROM A 
JOIN 
(select Id, 'b' as tablename from B
union all
select id, 'c' from c)
D ON D.ID = A.ID 

答案 2 :(得分:1)

问题陈述仍然不一致。我认为你的意思是表A与B相交的地方,其中A与C相交。在这种情况下,正确的TSQL是:

    SELECT A.ID
    FROM A
    LEFT OUTER JOIN B ON B.ID = A.ID
    LEFT OUTER JOIN C ON C.ID = A.ID
    WHERE B.ID IS NOT NULL OR C.ID IS NOT NULL 
    GROUP BY A.ID 
    ORDER BY A.ID

如果它们等于A.ID,则无需报告B.ID和C.ID. 分组依据是你不会重复A.ID。

答案 3 :(得分:0)

SELECT A.ID, B.ID, C.ID
FROM A
LEFT JOIN B ON B.ID = A.ID
LEFT JOIN C ON C.ID = A.ID
WHERE B.ID IS NOT NULL OR C.ID IS NOT NULL

或者,如果您只需要A中的字段,那么

SELECT A.ID
FROM A
INNER JOIN (
    SELECT B.ID FROM B
    UNION
    SELECT C.ID FROM C ) AS U ON U.ID = A.ID