我在以下结构中有两个表
表格 - MemoType
ID | MemoTypeID | MemoTypeName
1 1234 A
2 5678 B
表格 - 备忘录
ID | MemoTypeID | Memo | ExtRef
1 1234 TextOne XYZ
2 5678 TextTwo XYZ
3 1234 TextThree TUV
我们想更新这些表以反映以下数据
表格 - MemoType
ID | MemoTypeID | MemoTypeName
3 9999 NewCombinedMemo
表格 - 备忘录
ID | MemoTypeID | Memo | ExtRef
4 9999 <A> TextOne <B> TextTwo XYZ
5 9999 <A> TextThree TUV
备忘录表有大约200万行,ExtRef
有大约200,000个唯一值。
我的思路如下(使用.NET):填充List
表中所有唯一ExtRef
值的Memos
;对于每个唯一ExtRef
,请获取所有Memo
值的列表;根据需要连接字符串;为每个ExtRef
插入新记录;删除每个ExtRef
的其余记录。问题是这会导致大量的SQL操作。
请建议是否有其他有效的策略直接在SQL中实现这一点。
答案 0 :(得分:1)
这确实可以直接通过SQL实现,下面创建表变量来演示/测试样本数据并且不删除原始数据。
使用检查备忘录类型ID的子句可以很容易地删除原始数据,但我想暂缓这一点,直到我对这么大的表进行手动检查!
-- setting the scene
DECLARE @MemoType TABLE
(
Id int,
MemoTypeId int,
MemoTypeName varchar(30)
)
DECLARE @Memo TABLE
(
Id int identity(1,1),
MemoTypeId int,
Memo varchar(500),
ExtRef varchar(1000)
)
INSERT INTO @MemoType VALUES (1,1234,'A');
INSERT INTO @MemoType VALUES (2,1234,'B');
INSERT INTO @MemoType VALUES (3,9999,'NewCombinedMemo');
INSERT INTO @Memo VALUES (1234, 'TextOne', 'XYZ');
INSERT INTO @Memo VALUES (5678, 'TextTwo', 'XYZ');
INSERT INTO @Memo VALUES (1234, 'TextThree', 'TUV');
WITH cte(id, memotype, memotext, ref) as (
SELECT Id, MemoTypeId, Memo, ExtRef FROM @Memo
)
INSERT INTO @memo
SELECT 9999, stuff(memos,1,1,''),ref
FROM cte [outer]
CROSS APPLY (
SELECT ',' + memotext
FROM cte [inner]
WHERE [outer].ref = [inner].ref
FOR XML PATH('')
) n(memos)
GROUP BY ref, memos
select * from @memo
CTE逻辑/描述来自string concatenate in group by function with other aggregate functions - 添加逻辑以插入和删除前导逗号。