2013-06-25 66 views
1

我有兩個表的結構如下加入域的內容,並插入新記錄

表 - 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 

我們想更新這些表以反映以下數據

表 - 備註類型

ID | MemoTypeID | MemoTypeName 
3  9999   NewCombinedMemo 

表 - 備忘錄

ID | MemoTypeID | Memo     | ExtRef 
4 9999   <A> TextOne <B> TextTwo XYZ 
5 9999   <A> TextThree    TUV 

備忘錄表中有與ExtRef約200,000獨特價值約2萬行。

我的思路是沿着以下行(使用.NET):從填充表Memos所有獨特ExtRef值的List;對於每個獨特的ExtRef獲取所有Memo值的列表;根據需要連接字符串;爲每個ExtRef插入新記錄;刪除每個ExtRef的其餘記錄。問題是這會導致大量的sql操作。

請建議是否有其他有效的策略直接在SQL中實現此目的。

+0

不是獲得一串獨特的'ExtRef',然後查找字符串,做一個'GroupBy(x => x.ExtRef)'。 –

回答

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 - 將在邏輯插入和剝離出主導逗號。

  • 我把你原來的查詢放在CTE中。
  • 然後,我交叉應用了一個子查詢,它爲外部查詢中的每個引用獲取一個以逗號分隔的備忘錄集合 。
  • 由於我還選擇了備忘錄欄,我還不得不按 備忘錄欄進行分組。
  • 初始逗號需要用stuff函數剝離
  • 最後,插入結果。