【问题标题】:How can I override rows from another table?如何覆盖另一个表中的行?
【发布时间】:2020-11-25 21:40:25
【问题描述】:

我有两张桌子:

表A

ID  Name
--  ----
1   aaa
2   bbb
3   ccc
4   ddd

表B

ID  Name
--  --------
3   WWXXYYZZ

我想从两个表中进行选择,但跳过 TableB 中存在的行。结果应如下所示:

ID  Name
--  --------
1   aaa
2   bbb
3   WWXXYYZZ
4   ddd

我尝试过unionjoin,但不知道如何实现。

-- Did not work
select *
from TableA
union
select *
from TableB

-- Did not work
select *
from
(
    select *
    from TableA
) x
join
(
    select *
    from TableB
) y
on x.ID = y.ID

【问题讨论】:

  • @DaleK 我试过联合和内/左连接。
  • 如果 B 有一行值为 5... 会出现在结果中吗?
  • @TheImpaler 不,他们的 ID 必须匹配。 TableB 始终是 TableA 的子集。
  • @DaleK 更新问题

标签: sql sql-server join select nested-queries


【解决方案1】:

您可以离开加入 ba,并使用 coalesce 来选择 b 的行:

SELECT    a.id, COALESCE(b.name, a.name) AS name
FROM      a
LEFT JOIN b ON a.id = b.id

【讨论】:

    【解决方案2】:

    你可以这样做:

    select a.id, coalesce(b.name, a.name)
    from a left join b on a.id = b.id
    

    【讨论】:

    • 您可能打算离开联接,因为 b 是 a 的子集,而 OP 似乎想要 a 中的所有行。
    【解决方案3】:

    一种方法是union all:

    select b.*
    from b
    union all
    select a.*
    from a
    where not exists (select 1 from a where a.id = b.id);
    

    您还可以从 a 中选择并使用 b 中的值覆盖:

    select a.id, coalesce(b.name, a.name) as name
    from a left join
         b
         on a.id = b.id;
    

    【讨论】:

    • 这是一个复杂的大查询,我不能再次使用它。
    • @Farhan 为什么不呢?使用 CTE 或临时表来重用结果。
    • @Farhan 。 . .你意识到你接受的答案是这里的第二个查询。
    • @GordonLinoff 是的,但他先发布了。你想让我接受你的回答吗?
    • @Farhan 。 . .实际上,如果你看一下时间戳,这个是第一个发布的。无论如何,作为 OP,您可以接受您认为最好的任何答案。
    【解决方案4】:

    更复杂的方法使用ROW_NUMBER,如果您的查询比显示的复杂得多,这可能是必要的。它还处理了 TableB 中存在行但 TableA 中不存在行的情况(从您的问题中不清楚)。

    DECLARE @TableA TABLE (id INT, [Name] VARCHAR(12));
    DECLARE @TableB TABLE (id INT, [Name] VARCHAR(12));
    
    INSERT INTO @TableA (id, [Name])
    VALUES
    (1, 'aaa'),
    (2, 'bbb'),
    (3, 'ccc'),
    (4, 'ddd');
    
    INSERT INTO @TableB (id, [Name])
    VALUES
    (3, 'WWXXYYZZ'),
    (5, 'TTTGGG');
    
    SELECT id, [Name]
    FROM (
        SELECT id, [Name]
            , ROW_NUMBER() OVER (PARTITION BY id ORDER BY [Priority] DESC) Rn
        FROM (
            SELECT id, [Name], 0 [Priority]
            FROM @TableA
            UNION ALL
            SELECT id, [Name], 1 [Priority]
            FROM @TableB
        ) X
      ) Y
    WHERE Rn = 1;
    

    返回:

    1   aaa
    2   bbb
    3   WWXXYYZZ
    4   ddd
    5   TTTGGG
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-12
      • 1970-01-01
      • 1970-01-01
      • 2020-06-27
      • 2021-06-24
      相关资源
      最近更新 更多