加入具有多个匹配的表,但只返回指定的匹配

时间:2012-10-16 13:39:46

标签: sql sql-server-2008 tsql

我有3张桌子 表A包含我的查询将基于的数据。它包含id1。 表B是我的连接表,它包含我关注的2列:id1& ID2。

表C是我的查找表,它包含id2和ReasonName。我需要列'ReasonName'和表A中的所有数据。

如果我执行以下SQL:

 SELECT NAME, 
       STARTDATE, 
       ENDDATE, 
       REASON, 
       ID1 
FROM   TABLEA 
       LEFT JOIN TABLEB 
              ON TABLEA.ID1 = TABLEB.ID1

然后我可以对TableC进行第二次连接,但这就是问题所在。 TableC中有多个匹配,因此我的总数增加。我需要避免这种情况。 请参阅图像了解TableC的外观:

enter image description here

如果我的SQL语句现在如下所示:

 SELECT TABLEA.NAME, 
       TABLEA.STARTDATE, 
       TABLEA.ENDDATE, 
       TABLEA.REASON, 
       TABLEA.ID1, 
       TABLEC.REASONNAME 
FROM   TABLEA 
       LEFT JOIN TABLEB 
              ON TABLEA.ID1 = TABLEB.ID1 
       LEFT JOIN TABLEC 
              ON TABLEB.ID2 = TABLEC.ID2 

然后我的行增加大约1000.这是因为TableA.id1很可能匹配TableC中找到的多个id2。然后它复制除了不同的TableC.ReasonName之外的行。

在TableC中,我关注一个ReasonName。对于这个例子,我会说它是'reasonf'。

我需要的是从TableC中引入ReasonName,但只包含包含reasonf的那些,其余我想说的是NULL或者使用'No Reason'来执行COALESCE。 我已经尝试将WHERE子句放入语句中。请参见SQL:

 SELECT TABLEA.NAME, 
       TABLEA.STARTDATE, 
       TABLEA.ENDDATE, 
       TABLEA.REASON, 
       TABLEA.ID1, 
       TABLEC.REASONNAME 
FROM   TABLEA 
       LEFT JOIN TABLEB 
              ON TABLEA.ID1 = TABLEB.ID1 
       LEFT JOIN TABLEC 
              ON TABLEB.ID2 = TABLEC.ID2 
WHERE  TABLEC.ID2 = 'asd1f5as98a4' 

但是它只会带来那些与'reasonf'匹配的记录,我希望它显示reasonf人并忽略其余的(留空或其他东西)所以我没有重复但我的完整结果集

我想我可能需要更改为正确的联接或可能更改WHERE但我不完全确定。

2 个答案:

答案 0 :(得分:8)

将WHERE子句移动到连接...

select 
  TableA.name,
  TableA.startDate,
  TableA.endDate,
  TableA.Reason,
  TableA.id1,
  COALESCE(TableC.ReasonName, 'No Reason') AS FilteredReasonName
from
  TableA
left join
  TableB
    on  TableA.id1 = TableB.id1
    and TableB.id2 = 'asd1f5as98a4'
left join
  TableC
    on  TableB.id2 = TableC.id2

现在,TableB (复制源)只有在是ReasonF或者根本不加入时才加入。然后下一个连接将查找该代码的ReasonName。

如果未找到任何内容,则COALESCE()将'No Reason'替换为NULL。

答案 1 :(得分:1)

如果我理解你想要什么......

select 
    TableA.name,
    TableA.startDate,
    TableA.endDate,
    TableA.Reason,
    TableA.id1,
    TableC.ReasonName
from
TableA
left join TableB on TableA.id1 = TableB.id1
left join TableC on TableB.id2 = TableC.id2 and TableC.id2 = 'asd1f5as98a4'