复杂SQL MERGE / PIVOT未按预期排序

时间:2013-10-03 16:25:55

标签: sql merge sql-server-2008-r2 sql-order-by pivot

我有以下两张表; {/ 1}}使用

创建
ICD

其中CREATE TABLE ICD ([E] VARCHAR(8), [I] VARCHAR(8)); GO INSERT INTO ICD ([E], [I]) VALUES ('1', 'B1'), ('1', 'A1'), ('1', 'C23q'), ('1', '32Dq'), ('2', 'FFFq'), ('2', 'ERRE'), ('2', 'E'), ('3', 'WQWW'), ('3', 'WQ'), ('4', 'AAAA'); GO 给出了将O列插入另一个表的顺序。第二个表是I,这是使用

创建的
Episode

所以我的目标是将CREATE TABLE Episode ([EpiNum] VARCHAR(4), [SomeField] VARCHAR(4), [DX1] VARCHAR(10), [DX2] VARCHAR(10), [DX3] VARCHAR(10), [DX4] VARCHAR(10)); GO INSERT INTO Episode ([EpiNum], [SomeField], [DX1], [DX2], [DX3], [DX4]) VALUES ('1', 'Test', '', '', '', ''), ('2', 'Test', '', '', '', ''), ('3', 'Test', '', '', '', ''); GO 中的I列中的值插入ICD字段,具体取决于是否要插入值。忍受我;我有这个工作

DXn

这会产生一个MERGE INTO [Episode] AS T USING ( SELECT [EpiNum], [1], [2], [3], [4] FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY [EpiNum] ORDER BY [I]) AS rn FROM [ICD] ) AS p PIVOT ( MAX([I]) FOR rn IN ([1], [2], [3], [4])) AS p2 ) AS S ON T.[EpiNum] = S.[EpiNum] WHEN MATCHED THEN UPDATE SET [DX1] = S.[1], [DX2] = S.[2], [DX3] = S.[3], [DX4] = S.[4]; 表,看起来像

Episode

大!等等......不太好,PIVOT / MERGE中的EpiNum Test DX1 DX2 DX3 DX4 '1' 'Test' '32Dq' 'A1' 'B2' 'C23q' '2' 'Test' 'E' 'ERRE' 'FFFq' null '3' 'Test' 'WQ' 'WQWW' null null '4' 'Test' 'AAAA' null null null 破坏了数据的原始顺序。我试图通过添加另一个列ORDER BY来保持我想要的顺序来解决这个问题,因此O

定义
ICD

我正在尝试使用

CREATE TABLE ICD ([E] VARCHAR(8), [I] VARCHAR(8), [O] INT); GO INSERT INTO ICD ([E], [I], [O]) VALUES ('1', 'B1.2', 1), ('1', 'A1.2', 2), ('1', 'C23q', 3), ('1', '32Dq', 4), ('2', 'FFFq', 1), ('2', 'ERRE', 2), ('3', 'WQWW', 1), ('4', 'AAAA', 1); GO ORDER BY
O

但我收到以下消息

  

MERGE语句尝试多次更新或删除同一行。当目标行与多个源行匹配时会发生这种情况。 MERGE语句不能多次更新/删除目标表的同一行。优化ON子句以确保目标行最多匹配一个源行,或使用GROUP BY子句对源行进行分组。

如何正确推荐上述MERGE INTO [Episode] AS T USING ( SELECT [E], [1], [2], [3], [4] FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY [E] ORDER BY [O]) AS rn FROM [ICD] ) AS p PIVOT ( MAX([I]) FOR rn IN ([1], [2], [3], [4])) AS p2 ) AS S ON T.[E] = S.[E] WHEN MATCHED THEN UPDATE SET [DX1] = S.[1], [DX2] = S.[2], [DX3] = S.[3], [DX4] = S.[4]; 订单?

感谢您的时间

1 个答案:

答案 0 :(得分:1)

好吧,您的示例运行不正确,因为您在创建表和查询之间混合了列[E]Epinum。但假设这些列实际上是相同的列,那么您的第二个查询无效,因为您实际上并未对[E]列进行分组。试试这个:

MERGE INTO [Episode] AS T 
USING (
    SELECT [E], [1], [2], [3], [4] 
    FROM 
        ( 
             SELECT [E], [I], ROW_NUMBER() 
               OVER (PARTITION BY [E] ORDER BY [O]) AS rn
             FROM [ICD] 
        ) AS p
    PIVOT 
    (
       MAX([I]) 
       FOR rn IN ([1], [2], [3], [4])) AS p2
    ) AS S
ON T.[Epinum] = S.[E] 
WHEN MATCHED THEN
    UPDATE SET [DX1] = S.[1], [DX2] = S.[2], [DX3] = S.[3], [DX4] = S.[4];

现在,我真的不明白为什么你使用ROW_NUMBER()而不是简单地使用[O]列(这些值对我而言似乎相同),但这种方法都适用。