2011-09-21 45 views
2

错误措辞标题我的歉意。SQL服务器 - 有条件加入任何表不为空

我试图加入一个表,其他两个表

MasterTable 子表 SubTableArchive


所以,MasterTable包含一个ID字段之一。 SubTable和SubTableArchive包含用于连接的MasterTableId字段。

但是,数据将永远存在于这些子表之一中。所以我只想加入到其中有数据的表中。

但我知道这样做的唯一途径是通过加入到两个并使用isnull在我选择的所有字段上,并且其读取(和写入)很快变得复杂。 尤其是因为一些字段已经被包裹在ISNULL的

SELECT M.Id, ISNULL(S.Field1, SA.field1), ISNULL(S.field2, SA.Field2), 
SUM(CASE WHEN (ISNULL(S.Finished,SA.Finished)=1 AND ISNULL(ISNULL(S.ItemCode,SA.ItemCode),'')='') THEN 1 WHEN (ISNULL(S.Finished,SA.Finished)=0 AND ISNULL(ISNULL(S.AltItemCode,SA.AltItemCode),'')='') THEN 1 ELSE 0 END) AS SummaryField 
FROM MAsterTable M 
LEFT OUTER JOIN SubTable S ON S.MasterTableId = M.Id 
LEFT OUTER JOIN SubTableArchive SA ON S.MasterTableId = M.Id 
GROUP BY M.Id, ISNULL(S.Field1, SA.field1), ISNULL(S.field2, SA.Field2) 

所以这是工作,但它不是漂亮。 这是一个样本,但真正的查询更长,更复杂。

我希望SQL可能有某种内置的条件加入功能。 有些事情要做,我想做的事情离开查询itslef有点友好。

回答

4

另一种选择是使用UNION,然后使用内部连接

SELECT M.x, S.x 
FROM MAsterTable M INNER JOIN SubTable S ON S.MasterTableId = M.Id 
UNION 
SELECT M.x, STA.x 
FROM MAsterTable M INNER JOIN SubTableArchive STA ON STA.MasterTableId = M.Id 

从一个维修点,如果你把上面的工会视图,你可以再申请,其中过滤和排序的视图,这应该简化事宜。

1

不,不幸的是,没有。

1

试试这个

SELECT M.Id, S.Field1,S.field2, 
    SUM(CASE WHEN S.Finished=1 AND ISNULL(S.ItemCode,'')='') 
     THEN 1 
     WHEN S.Finished=0 AND ISNULL(S.AltItemCode,'')='') 
     THEN 1 ELSE 0 END) AS SummaryField 
    FROM MAsterTable M 
    JOIN (
     SELECT id,field1,field2,ItemCode,AltItemCode,finished 
     FROM subTable 
     UNION 
     SELECT id,field1,field2,ItemCode,AltItemCode,finished 
     FROM subTableArchive 
    ) S ON S.id = M.Id 

    GROUP BY M.Id, S.Field1,S.field2 
2

使用子选择,或者使用语句更好(代码未测试):

WITH SubTable_WithArchive 
AS (SELECT Field1, Field2, Finished, ItemCode, AltItemCode, MasterTableID 
    FROM SubTable 
    UNION ALL 
    SELECT Field1, Field2, Finished, ItemCode, AltItemCode, MasterTableID 
    FROM SubTableArchive 
) 
SELECT M.Id, 
     S.Field1, 
     S.Field2, 
     SUM(CASE 
       WHEN s.Finished = 1 AND ISNULL(s.ItemCode, '') == '' THEN 1 
       WHEN s.Finished = 0 AND ISNULL(s.AltItemCode, '') == '' THEN 1 
       ELSE 0 
      END) 
      AS SummaryField 

FROM   MasterTable M 
LEFT OUTER JOIN SubTable_WithArchive S 
      ON S.MasterTableId = M.Id 
GROUP BY  M.Id, S.Field1, s.field2 
0

因为从MasterTable一个ID值将只在一个表(SubTableSubTableArchive存在)您可以使用此查询:

SELECT MasterTableId Id, Field1, Field2, 
SUM(CASE 
WHEN Finished=1 AND ItemCode IS NULL THEN 1 --OR ISNULL(ItemCode,'') = '' 
WHEN Finished=0 AND AltItemCode IS NULL THEN 1 --OR ISNULL(AltItemCode,'') = '' 
ELSE 0 
END) AS SummaryField 
FROM SubTable 
GROUP BY 1, 2, 3 

UNION ALL 

SELECT MasterTableId Id, Field1, Field2, 
SUM(CASE 
WHEN Finished=1 AND ItemCode IS NULL THEN 1 --OR ISNULL(ItemCode,'') = '' 
WHEN Finished=0 AND AltItemCode IS NULL THEN 1 --OR ISNULL(AltItemCode,'') = '' 
ELSE 0 
END) AS SummaryField 
FROM SubTableArchive 
GROUP BY 1, 2, 3