【问题标题】:TSQL - Union records based on partial uniquenessTSQL - 基于部分唯一性的联合记录
【发布时间】:2020-02-28 20:11:33
【问题描述】:

样本数据

DECLARE @T1 TABLE (Id INT, Val1 VARCHAR(20), Val2 VARCHAR(20), [Group] INT);

INSERT INTO @T1
SELECT 1, 'One', '01', 1
UNION
SELECT 2, 'Two', '02', 1
UNION
SELECT 3, 'Three', '03', 1
UNION
SELECT 3, 'Threeeee', '03', 2
UNION
SELECT 4, 'Four', '04', 2
UNION
SELECT 5, 'Five', '05', 2
UNION
SELECT 4, 'Four', '04', 3
UNION
SELECT 5, 'Five', '050', 3
UNION
SELECT 6, 'Six', '06', 3;

当前插入的数据:

1   One         01  1
2   Two         02  1
3   Three       03  1
3   Threeeee    03  2
4   Four        04  2
5   Five        05  2
4   Four        04  3
5   Five        050 3
6   Six         06  3

目标: 仅基于 [Id] 字段的唯一性将记录插入表变量(或 cte/temp 表)。 “UNION”不会这样做,因为至少,[Group] 将根据 [Id] 制作重复记录...唯一。哦,[Group]值基本上表示重要性级别,1 =这些记录应该首先插入,3 =这些记录应该最后插入,在确保目标表中没有具有相同[Id]值的其他记录之后.

预计插入数据:

1   One         01  1
2   Two         02  1
3   Three       03  1
4   Four        04  2
5   Five        05  2
6   Six         06  3

我可以通过首先将 [Group] = 1 记录插入 @T1 来做到这一点。然后为 [Group] = 2 编写另一个插入,其中 [Id] 不存在,依此类推。但我正在寻找一种有效的方法。我想让 insert 高效。

【问题讨论】:

    标签: sql sql-server tsql sql-server-2016


    【解决方案1】:

    首先创建一个CTE,其中包含您要插入的所有行:

    WITH cte(Id, Val1, Val2, [Group]) AS (
      SELECT 1, 'One', '01', 1
      UNION ALL
      SELECT 2, 'Two', '02', 1
      UNION ALL
      SELECT 3, 'Three', '03', 1
      UNION ALL
      SELECT 3, 'Threeeee', '03', 2
      UNION ALL
      SELECT 4, 'Four', '04', 2
      UNION ALL
      SELECT 5, 'Five', '05', 2
      UNION ALL
      SELECT 4, 'Four', '04', 3
      UNION ALL
      SELECT 5, 'Five', '050', 3
      UNION ALL
      SELECT 6, 'Six', '06', 3
    )
    

    然后在INSERT 语句中你可以使用NOT EXISTS:

    INSERT INTO @T1
    SELECT c.* FROM cte c
    WHERE NOT EXISTS (
      SELECT 1 FROM cte
      WHERE Id = c.ID AND [Group] < c.[Group]
    );
    

    demo

    ROW_NUMBER()窗口函数:

    INSERT INTO @T1
    SELECT t.Id, t.Val1, t.Val2, t.[Group] 
    FROM (
      SELECT *, ROW_NUMBER() OVER (PARTITION BY Id ORDER BY [GROUP]) rn
      FROM cte
    ) t
    WHERE t.rn = 1;
    

    请参阅demo
    结果:

    > Id | Val1  | Val2 | Group
    > -: | :---- | :--- | ----:
    >  1 | One   | 01   |     1
    >  2 | Two   | 02   |     1
    >  3 | Three | 03   |     1
    >  4 | Four  | 04   |     2
    >  5 | Five  | 05   |     2
    >  6 | Six   | 06   |     3
    

    【讨论】:

    • 有趣的方法。在插入之前暂存完整数据,并在插入时使用 window fx 对其进行过滤。真的很酷。谢谢你,干杯!
    猜你喜欢
    • 1970-01-01
    • 2016-11-01
    • 2023-02-06
    • 2016-02-20
    • 2023-04-04
    • 2015-06-27
    • 1970-01-01
    • 2021-10-12
    • 2019-05-16
    相关资源
    最近更新 更多