使用相同的键加入/合并多个表

时间:2017-01-15 13:58:23

标签: sql-server

我有几张表,我加入了这样的表:

SELECT *
FROM   tableA AS A
       FULL OUTER JOIN tableB AS B
                    ON B.KEY = A.KEY
       FULL OUTER JOIN tableC AS C
                    ON C.KEY = A.KEY
       FULL OUTER JOIN tableD AS D
                    ON D.KEY = A.KEY 

这样可以正常工作,但我有时会得到单独的行,其中所有表中都不存在该键。

实施例

WITH tableA([KEY], payloadColumn) AS
(
SELECT 1, 'var_A1'
), tableB([KEY], payloadColumn) AS
(
SELECT 2, 'var_B2'
), tableC([KEY], payloadColumn) AS
(
SELECT 1, 'var_C1'
), tableD([KEY], payloadColumn) AS
(
SELECT 2, 'var_D2'
)
SELECT * FROM tableA as A
FULL OUTER JOIN tableB as B ON B.[KEY] = A.[KEY]
FULL OUTER JOIN tableC as C ON C.[KEY] = A.[KEY]
FULL OUTER JOIN tableD as D ON D.[KEY] = A.[KEY]

返回

+------+---------------+------+---------------+------+---------------+------+---------------+
| KEY  | payloadColumn | KEY  | payloadColumn | KEY  | payloadColumn | KEY  | payloadColumn |
+------+---------------+------+---------------+------+---------------+------+---------------+
| 1    | var_A1        | NULL | NULL          | 1    | var_C1        | NULL | NULL          |
| NULL | NULL          | 2    | var_B2        | NULL | NULL          | NULL | NULL          |
| NULL | NULL          | NULL | NULL          | NULL | NULL          | 2    | var_D2        |
+------+---------------+------+---------------+------+---------------+------+---------------+

但是我需要它们全部在结果的同一行(2不是两行)。我怎么能这样做?

2 个答案:

答案 0 :(得分:3)

您可以使用COALESCE

WITH tableA([KEY], payloadColumn)
     AS (SELECT 1,
                'var_A1'),
     tableB([KEY], payloadColumn)
     AS (SELECT 2,
                'var_B2'),
     tableC([KEY], payloadColumn)
     AS (SELECT 1,
                'var_C1'),
     tableD([KEY], payloadColumn)
     AS (SELECT 2,
                'var_D2')
SELECT COALESCE(A.[KEY], B.[KEY], C.[KEY], D.[KEY]) AS [KEY],
       A.payloadColumn,
       B.payloadColumn,
       C.payloadColumn,
       D.payloadColumn
FROM   tableA AS A
       FULL OUTER JOIN tableB AS B
                    ON B.[KEY] = A.[KEY]
       FULL OUTER JOIN tableC AS C
                    ON C.[KEY] = COALESCE(A.[KEY], B.[KEY])
       FULL OUTER JOIN tableD AS D
                    ON D.[KEY] = COALESCE(A.[KEY], B.[KEY], C.[KEY]); 

返回

+-----+---------------+---------------+---------------+---------------+
| KEY | payloadColumn | payloadColumn | payloadColumn | payloadColumn |
+-----+---------------+---------------+---------------+---------------+
|   1 | var_A1        | NULL          | var_C1        | NULL          |
|   2 | NULL          | var_B2        | NULL          | var_D2        |
+-----+---------------+---------------+---------------+---------------+

如果所有表都在[KEY] INCLUDE (payloadColumn)上有覆盖索引,则执行计划可以将合并连接链接在一起。

enter image description here

答案 1 :(得分:3)

这是我提出的解决方案,基于以前版本的OP中的草案,以及他们的上一次编辑:

CREATE VIEW ABCD

AS

SELECT [KEY] FROM tableA
UNION
SELECT [KEY] FROM tableB
UNION
SELECT [KEY] FROM tableC
UNION
SELECT [KEY] FROM tableD

创建视图可能不是一种选择;在这种情况下,重写为CTE。 至少以这种方式,执行计划将继续使用索引(假设[KEY]是PK或索引)。

SELECT
  K.[KEY] as sameKey,
  A.payloadColumn,
  B.payloadColumn,
  C.payloadColumn,
  D.payloadColumn
FROM ABCD K
LEFT JOIN tableA A ON A.[KEY]=K.[KEY]
LEFT JOIN tableB B ON B.[KEY]=K.[KEY]
LEFT JOIN tableC C ON C.[KEY]=K.[KEY]
LEFT JOIN tableD D ON D.[KEY]=K.[KEY]

如果这让你的想法有误,请详细说明。