【问题标题】:I would like to update table using merge and my table source will use cross join我想使用合并更新表,我的表源将使用交叉连接
【发布时间】:2023-04-07 12:33:01
【问题描述】:

我有一个 Table1:

IdT1 : 11, 12, 13

IdT1Group : 30,30,30

表2:

IdT2 : 1, 2, 3, 4

IdT1 : 11, 11, 12, 12

Detail : A, B, A, B

AND 用户定义的表类型@T2:

IdT2 : 1, 2, 3

IdT1 : 11,11,11

Detail: A,B,C

我想将 Table2 更新为:

IdT2 : 1,2,5, 3,4,6, 7,8,9

IdT1 : 11,11,11, 12,12,12, 13,13,13

Detail : A,B,C, A,B,C, A,B,C

所以,我是在 StoredProcedure 中使用合并:

;WITH Table2
    AS (SELECT Table2.* FROM Table2 INNER JOIN Table1 ON Table2.IdT1 = Table1.IdT1 AND IdT1Group = 30)
    MERGE INTO Table2 AS tblTarget
    USING (SELECT @T2.*, T1Item.IdT1 AS T1Id FROM @T2 CROSS JOIN Table1 where IdT1Group = 30)
            AS tblSource
        ON tblTarget.IdT1 = tblSource.T1Id And tblTarget.IdT2 = tblSource.IdT2

WHEN MATCHED THEN
    UPDATE 
    SET Detail = tblSource.Detail
WHEN NOT MATCHED BY SOURCE THEN
    DELETE
WHEN NOT MATCHED BY TARGET THEN            
    INSERT (IdItem, IdT2, Detail)
    VALUES (tblSource.IdT1,
            tblSource.IdT2, tblSource.Detail);

但是在我尝试了我的代码之后,我的 table2 变成了:

IdT2 : 1,2,5, 6,7,8, 9,10,11

IdT1 : 11,11,11, 12,12,12, 13,13,13

Detail: A,B,C, A,B,C, A,B,C

应该是这样的:

IdT2 : 1,2,5, 3,4,6, 7,8,9

IdT1 : 11,11,11, 12,12,12, 13,13,13

Detail : A,B,C, A,B,C, A,B,C

【问题讨论】:

  • 请花一些时间重新格式化您的示例数据/表格。
  • 您对表和数据的描述非常混乱。而且我不知道为什么你会期望从合并中得到你所期望的。

标签: sql sql-server stored-procedures merge cross-join


【解决方案1】:

我认为输出应该如下所示,因为其中一个值被删除了。此外,我认为您在 IdT2 的 Table2 中有一个标识列或增量值。 当您删除一个项目时,增加的价值不会被扣除。

输出

        IdT2        IdT1        Detail
        ----------- ----------- -------
        1           11          A
        2           11          B
        5           11          C
        3           12          C
        6           12          A
        7           12          B
        8           13          A
        9           13          B
        10          13          C

SQL 语句(注意:创建 # 个表而不是物理表来实现这一点)

    create table #Table1
    (
    IdT1    int , IdT1Group int
    )

    insert into #Table1
    select 11 IdT1,30  IdT1Group union all
    select 12 IdT1,30  IdT1Group union all
    select 13 IdT1,30  IdT1Group

    create table #Table2
    (
    IdT2 int identity(1,1),   IdT1     int , Detail varchar(100)
    )

    insert into #Table2
    SELECT   11 IdT1 ,'A' Detail union all
    SELECT   11 ,'B'      union all
    SELECT   12 ,'A'      union all
    SELECT   12 ,'B'

    declare @T2  table  
    (
    IdT2 int ,   IdT1     int , Detail varchar(100)
    )

    insert into @T2
    SELECT 1 IdT2 ,  11 IdT1 ,'A' Detail union all
    SELECT 2 ,  11 ,'B' union all
    SELECT 3 ,  12 ,'C'

    MERGE INTO #Table2 AS tblTarget
    USING (SELECT T2.*, T1Item.IdT1 AS T1Id FROM @T2 T2 CROSS JOIN #Table1 T1Item where IdT1Group = 30)
            AS tblSource
        ON  tblTarget.IdT1 = tblSource.T1Id   And tblTarget.IdT2 = tblSource.IdT2--tblTarget.IdT1 = tblSource.T1Id And tblTarget.IdT2 = tblSource.IdT2 

    WHEN MATCHED THEN
        UPDATE 
        SET Detail = tblSource.Detail
    WHEN NOT MATCHED BY SOURCE THEN
        DELETE
    WHEN NOT MATCHED BY TARGET THEN            
        INSERT (IdT1,  Detail)
        VALUES (tblSource.T1Id,
                 tblSource.Detail);

    select * from #Table2
    order by 2,1

    drop table #Table1
    drop table #Table2

【讨论】:

  • 谢谢你的建议,我现在就试试
猜你喜欢
  • 2021-01-01
  • 2019-11-04
  • 1970-01-01
  • 2021-12-24
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 2013-03-29
  • 1970-01-01
相关资源
最近更新 更多