LEFT和RIGHT中的所有行都放在堆栈中

时间:2019-01-28 10:16:59

标签: sql sql-server

我必须将表A中的所有行与表B中的匹配行完全堆叠在同一列下。

表A:

    SomeCol  | Value
    1        | NULL
    1        | NULL
    2        | NULL
    2        | NULL

表B:

SomeCol      | Value
    1        | X
    1        | Y
    2        | Z
    2        | A

我尝试使用OUTER APPLY运算符,因为它的定义表明它将左表(A)中的行与右表(B)中不匹配的行一起使用。

SELECT 
    A.SomeCol,
    A.Value,
    B.*
FROM
    TableA as A
OUTER APPLY(
    SELECT X.SomeCol, X.Value FROM TableB AS X
    WHERE A.SomeCol = X.SomeCol
) AS B

我希望这样:

SomeCol | Value
1       | NULL
1       | NULL
1       | X
1       | Y
2       | NULL
2       | NULL
2       | Z
2       | A

简短更新:我忘了提一下,我不允许使用UNION,因为我只想返回表A中现有行的结果。

3 个答案:

答案 0 :(得分:2)

在子查询中使用union all可能是最简单的

select u.SomeCol, u.Value
from (
  select SomeCol, Value
  from A
  union all
  select SomeCol, Value
  from B
) as u
order by u.SomeCol;

问题更新后编辑

没有什么可以阻止内部查询具有过滤器的:

select u.SomeCol, u.Value
from (
  select SomeCol, Value
  from A
  union all
  select SomeCol, Value
  from B
  where SomeCol in (select SomeCol from A)
) as u
order by u.SomeCol;

仅包含B中具有匹配行的A中的行。我仍将在此处使用union,以使B中的行在查询的输出中保持单独的行。

答案 1 :(得分:0)

您可以尝试

   Create Table TableA
(
SomeCol int, Value Varchar(5)
)

Create Table TableB
(
SomeCol int, Value Varchar(5)
)

Insert into TableA (SomeCol, Value) Values     
    (1, NULL),
    (1, NULL),
    (2, NULL),
    (2, NULL)

Insert into TableB (SomeCol, Value) Values     
    (1, 'X'),
    (1, 'Y'),
    (2, 'Z'),
    (2, 'A')

    SELECT SomeCol, Value FROM TableA
UNION ALL
SELECT DISTINCT SomeCol, Value FROM(
SELECT 
    B.SomeCol, B.Value
FROM
    TableA as A
INNER JOIN TableB AS B
    ON A.SomeCol = B.SomeCol
)a

输出如下所示

SomeCol Value
-------------
1       NULL
1       NULL
2       NULL
2       NULL
1       X
1       Y
2       A
2       Z

您可以找到实时演示here

答案 2 :(得分:0)

如果我正确理解了该请求,则希望重新调整TableA中的所有行,而仅调整TableB中的匹配行,而不是在同一元组/行中(根据您的期望)。

这意味着完全联接将不起作用。我认为您应该像这样一个工会:

-- all rows from TableA
 SELECT 
    A.SomeCol,
    A.Value,
FROM TableA

UNION ALL 
-- mathing rows in TableB
 SELECT 
    A.SomeCol,
    A.Value,
FROM TableA
    INNER JOIN TableB ON TableB.SomeCol = TableA.SomeCol