【问题标题】:Inserting AND/OR Updating records based off of values from another table根据另一个表中的值插入和/或更新记录
【发布时间】:2020-07-31 22:23:10
【问题描述】:

基本上,我要做的是在源表中创建一个新的重复行,如果 CANID 作为目标表中的副本存在。例如,在这个集合中,CANID '2' 在目标表中作为副本存在,但在源表中,它只存在一次。我想要完成的是让这个脚本使用下一个可用的 CANID 创建另一行并复制其他列的值。

运行后,结果将如下所示。请注意如何更改目标表中的 CANID(对于 ACTID 6969)以反映正确的 CANID

源表:

CREATE TABLE [dbo].[sourcetable]
(
    [CANID] [int] NULL,
    [COLID] [int] NULL,
    [Value1] [varchar](255) NULL,
    [Value2] [varchar](255) NULL,
    [Value3] [varchar](255) NULL,
    [Value4] [varchar](255) NULL,
    [Value5] [varchar](255) NULL
) ON [PRIMARY]
GO

Sourcetable 的示例数据

INSERT INTO sourcetable (CANID,COLID,Value1,Value2,Value3,Value4,Value5) VALUES (1,21,'0.25','6.25','Chicago','-0.25','16');
INSERT INTO sourcetable (CANID,COLID,Value1,Value2,Value3,Value4,Value5) VALUES (2,65,'0.65','6.19','Dallas','0.15','65');
INSERT INTO sourcetable (CANID,COLID,Value1,Value2,Value3,Value4,Value5) VALUES (3,91,'1.65','3.25','Denver','NULL','65');
INSERT INTO sourcetable (CANID,COLID,Value1,Value2,Value3,Value4,Value5) VALUES (4,55,'1','42','Miami','0.25','NULL');

目标表:

CREATE TABLE [dbo].targettable 
(
    [CANID] [int] NULL,
    [ACCTID] [int] NULL,
) ON [PRIMARY]
GO

目标表的示例数据:

INSERT INTO targettable (CANID,ACCTID) VALUES ('1','6586');
INSERT INTO targettable (CANID,ACCTID) VALUES ('2','6658');
INSERT INTO targettable (CANID,ACCTID) VALUES ('2','6969');
INSERT INTO targettable (CANID,ACCTID) VALUES ('3','2245');
INSERT INTO targettable (CANID,ACCTID) VALUES ('4','2365');

我尝试了递归 CTE,但它不适合我。任何帮助将不胜感激。

SQL Server 2012。

【问题讨论】:

    标签: sql sql-server sql-update sql-insert window-functions


    【解决方案1】:

    一种方法是连接两个表并使用窗口函数生成源表中的缺失行,方法是将源中每个canid 的行数与row_number() 进行比较overcanid 目标中的分区。

    然后,剩下要做的就是插入目标表,根据需要使用row_number() 增加最大值canid

    insert into sourcetable (canid, colid, value1, value2, value3, value4, value5)
    select 
        max_can_id + row_number() over(order by s.canid),
        s.colid,
        s.value1,
        s.value2,
        s.value3,
        s.value4,
        s.value5
    from (
        select 
            s.*, 
            count(*) over(partition by canid) cnt,
            max(canid) over() max_can_id
        from sourcetable s
    ) s
    inner join (
        select canid, row_number() over(partition by canid order by (select null)) rn
        from targettable
    ) t on t.canid = s.canid and s.cnt < t.rn   
    

    如果需要,此查询将愉快地生成几行。

    Demo on DB Fiddle

    犬类 |碰撞 |价值1 |价值2 |价值3 |价值4 |价值5 ----: | ----: | :----- | :----- | :-------- | :----- | :----- 1 | 21 | 0.25 | 6.25 |芝加哥 | -0.25 | 16 2 | 65 | 0.65 | 6.19 |达拉斯 | 0.15 | 65 3 | 91 | 1.65 | 3.25 |丹佛 |空 | 65 4 | 55 | 1 | 42 |迈阿密 | 0.25 |空值 5 | 65 | 0.65 | 6.19 |达拉斯 | 0.15 | 65

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-02
      • 1970-01-01
      • 1970-01-01
      • 2023-04-08
      • 2019-01-10
      • 2010-10-17
      相关资源
      最近更新 更多