使用SQL SERVER FOR XML PATH將多個結果集轉換成一行並進行去重處理


在一個醫葯行業的系統中需要根據患者的接觸記錄ID獲取不同接觸類型的集合,效果像這樣
 
 
--患者接觸記錄信息,一個患者可以有N個不同的接觸記錄,每個接觸記錄又有N個接觸類型記錄
IF OBJECT_ID ('dbo.TEST') IS NOT NULL
DROP TABLE dbo.TEST
GO
CREATE TABLE dbo.TEST
(
ID INT IDENTITY (1000,1) NOT NULL,
cid INT,--接觸記錄號
REMARK VARCHAR (4000),
CONTACTTYPE VARCHAR (20),
DESCRIBE VARCHAR (4000),
ADDDATE DATETIME
)
GO
--測試數據,包含重復類型
INSERT INTO dbo.TEST (cid, REMARK, CONTACTTYPE, DESCRIBE, ADDDATE)
VALUES (81667,'咨詢備注','ContactType_1', NULL,'2014-06-03 09:53:24')
,(81667,'回訪備注','ContactType_2', NULL,'2014-06-03 09:53:24')
,(81667,'咨詢備注','ContactType_1', NULL,'2014-06-03 09:53:24.92')
,(81667,'回訪備注','ContactType_2','回訪找棕','2014-06-03 09:53:24.927')
,(81667,'隨訪備注','ContactType_3','隨訪詳情','2014-06-03 09:53:24.933')
,(81667,'通知備注','ContactType_4','通知內容描述','2014-06-03 09:53:24.94')
,(81667,'預約備注','ContactType_5','預約內容','2014-06-03 09:53:24.947')
,(81667,'回復備注','ContactType_6','回復測試。。。。','2014-06-03 09:53:24.95')
,(81679,'咨詢備注','ContactType_1', NULL,'2014-06-03 10:53:53.743')
,(81679,'回訪備注','ContactType_2','回訪內容描述','2014-06-03 10:53:53.75')
,(81679,'隨訪備注','ContactType_3','隨訪詳情','2014-06-03 10:53:53.757')
,(81679,'通知備注','ContactType_4','通知內容描述','2014-06-03 10:53:53.763')
,(81679,'預約備注','ContactType_5','預約內容','2014-06-03 10:53:53.767')
,(81679,'回復備注','ContactType_6','回復內容','2014-06-03 10:53:53.777')

 

之前寫的一個Sql方法里是這樣的在正常的情況下沒有問題,但如果一個接觸記錄存在兩個相同的接觸類型的話就會存在相同的接觸類型(此問題有可能是代碼導致的,但我並不能直接更改代碼)
既然不能更改代碼那只能通過數據庫來處理了
--之前的sql方法,有可以會返回相同的類型則
DECLARE @SNvarchar(2000)
SET @S=''
SELECT @S=@S+'/'+(CASE ContactType
WHEN 'ContactType_1'THEN '咨詢'
WHEN 'ContactType_2'THEN '回訪'
WHEN 'ContactType_3'THEN '隨訪'
WHEN 'ContactType_4'THEN '通知'
WHEN 'ContactType_5'THEN '預約'
WHEN 'ContactType_6'THEN '回復'
END)
FROM test WHERE CID=81667
PRINT @s

 

以下效果顯然不是我想要的
 
 
通過幾個小時的努力終於通過Sql完美解決,時間全部浪費在去重的問題上
想到過的解決方法
1.在之前Sql里直接加入DISTINCT進行數據去重但一直出現錯誤" 關鍵字 'DISTINCT' 附近有語法錯誤。 Severity 15 "
2.使用臨時表,先將數據查詢出來並插入臨時表,然后再循環臨時表並添加到字符串,添加時如果存在則不會重復添加
3.先按照原來的方法得到可能重復的字符串,然后對字符串進行去重處理
4.使用我現在的方法即用for xml和 DISTINCT 得到已經去重的字符串然后再賦予一個變量
 
FOR XML需要SqlServer 2005+版本支持
--新的Sql方法,通過FOR XML PATH和DISTINCT進行去重處理 

DECLARE @SNvarchar(2000)
--無法在包含DISTINCT關鍵字的查詢中將結果賦予變量,以下Sql將出現錯誤"關鍵字 'DISTINCT' 附近有語法錯誤。 Severity 15"
-- SELECT @s= DISTINCT -- ( '/'+(CASE ContactType -- WHEN 'ContactType_1'THEN '咨詢' -- WHEN 'ContactType_2'THEN '回訪' -- WHEN 'ContactType_3'THEN '隨訪' -- WHEN 'ContactType_4'THEN '通知' -- WHEN 'ContactType_5'THEN '預約' -- WHEN 'ContactType_6'THEN '回復' -- END) -- ) -- FROM test WHERE Cid=81667 -- FOR XML PATH('')
SELECT @S=(
SELECT DISTINCT (
'/'+(CASE ContactType
WHEN 'ContactType_1'THEN '咨詢'
WHEN 'ContactType_2'THEN '回訪'
WHEN 'ContactType_3'THEN '隨訪'
WHEN 'ContactType_4'THEN '通知'
WHEN 'ContactType_5'THEN '預約'
WHEN 'ContactType_6'THEN '回復'
END)
)
FROM test WHERE Cid=81667
FOR XML PATH('')
)
PRINT @s

 

通過FOR XML和 DISTINCT 去重后的效果
 
 
可以看到使用for xml path可以很容易的將多選結果集轉換成一行
 
參考:
 
 

來自為知筆記(Wiz)




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM