我需要将单列数据拆分为多列 我有这样的数据
ID NAME COMMENT
1 TEST Reg: 0001 Inv: B0001 Cus: A0001 Br: F0001
2 TEST1 Reg: 0002 Inv: B0002 Cus: A0002 Br: F0002
3 TEST2 Reg: 0003 Inv: B0003 Cus: A0003 Br: F0003
4 TEST3 Reg: 0004 Inv: B0004 Cus: A0004 Br: F0004
5 TEST4 Reg: 0005 Inv: B0005 Cus: A0005 Br: F0005
5 TEST4 Reg: 00010 Inv: B00010 Cus: A00010 Br: F00010
我需要在表注释中拆分数据,所以它变成这样:
REG INV BR
0001 B0001 F0001
0002 B0002 F0002
0003 B0003 F0003
0004 B0004 F0004
0005 B0005 F0005
00010 B00010 F00010
有任何建议怎么做?
我的代码。
;WITH Split_Names (Comment)
AS
-- Define the CTE query.
(
SELECT
CONVERT(XML,'<COMMENTS><Comment>'
+ REPLACE(
REPLACe(
REPLACE(
REPLACE(
REPLACE(
REPLACE(Comment,'Reg:',''),'Inv:',','),'Cus:',','),'Br:',','),' ' ,'')
,',', '</Comment><Comment>') + '</Comment></COMMENTS>') AS xmlComments
FROM GenTransaction
)
-- Define the outer query referencing the CTE name.
SELECT
Comment.value('/COMMENTS[1]/Comment[1]','varchar(100)') AS Reg,
Comment.value('/COMMENTS[1]/Comment[2]','varchar(100)') AS Inv,
Comment.value('/COMMENTS[1]/Comment[3]','varchar(100)') AS Cus,
Comment.value('/COMMENTS[1]/Comment[4]','varchar(100)') AS Br
FROM Split_Names
答案 0 :(得分:2)
以下解决方案应该有效
[1]无论哪个订单用于Comment
列(Reg, Inv, Cus Br
或Cus, Br, Reg, Inv
或其他内容)以及
[2] Comment
列的某些项目可能会丢失(例如TEST4 / Cus缺失)
[3]如果Comment
包含XML保留字符,则应使用REPLACE(t1.Comment,
而不是REPLACE((SELECT t1.Comment AS '*' FOR XML PATH('')),
DECLARE @Table1 TABLE (
ID INT NOT NULL,
Name NVARCHAR(50),
Comment NVARCHAR(500)
);
INSERT @Table1 (ID, Name, Comment)
VALUES
(1, 'TEST ', 'Reg: 0001 Inv: B0001 Cus: A0001 Br: F0001'),
(2, 'TEST1', 'Reg: 0002 Inv: B0002 Cus: A0002 Br: F0002'),
(3, 'TEST2', 'Reg: 0003 Inv: B0003 Cus: A0003 Br: F0003'),
(4, 'TEST3', 'Reg: Coco&Jambo Inv: B0004 Cus: A0004 Br: F0004'), -- & = reserved XML char
(5, 'TEST4', 'Reg: 0005 Inv: B0005 Br: F0005'), -- Cus is missing
(5, 'TEST4', 'Cus: 3333 Br: 4444 Reg: 1111 Inv: 22222'); -- Different order
;WITH BaseQuery AS
(
SELECT t1.ID, t1.Name,
CONVERT(XML, '<root><item>'
+ REPLACE(
REPLACE(
REPLACE(
REPLACE((SELECT t1.Comment AS '*' FOR XML PATH('')),
'Reg:',
'</item><item type="Reg">'),
'Inv:',
'</item><item type="Inv">'),
'Cus:',
'</item><item type="Cus">'),
'Br:',
'</item><item type="Br">') + '</item></root>') CommentAsXml
FROM @Table1 t1
)
SELECT bq.ID, bq.Name,
Reg = LTRIM(RTRIM(bq.CommentAsXml.value('(root/item[@type="Reg"])[1]', 'VARCHAR(11)'))),
Inv = LTRIM(RTRIM(bq.CommentAsXml.value('(root/item[@type="Inv"])[1]', 'VARCHAR(11)'))),
Cus = LTRIM(RTRIM(bq.CommentAsXml.value('(root/item[@type="Cus"])[1]', 'VARCHAR(11)'))),
Br = LTRIM(RTRIM(bq.CommentAsXml.value('(root/item[@type="Br"])[1]', 'VARCHAR(11)')))
FROM BaseQuery bq
结果:
答案 1 :(得分:1)
试试这个。基本上我正在做的是用逗号替换Reg:Inv:etc,删除空格并使用XML来派生列值。
所以我正在考虑下面的@Bogdan Sahlean解决方案来处理评论字段中的XMl特殊字符。试试这个;
;WITH Split_Names (COMMENT)
AS
-- Define the CTE query.
(
SELECT
CONVERT(XML,'<COMMENTS><COMMENT>'
+
REPLACE(
REPLACe(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
(SELECT Comment AS '*' FOR XML PATH(''))
,'Reg:',''),'Inv:',','),'Cus:',','),'Br:',','),' ' ,'')
,',', '</COMMENT><COMMENT>') + '</COMMENT></COMMENTS>') AS xmlname
FROM
GenTransaction
)
-- Define the outer query referencing the CTE name.
SELECT
COMMENT.value('/COMMENTS[1]/COMMENT[1]','varchar(100)') AS Reg,
COMMENT.value('/COMMENTS[1]/COMMENT[2]','varchar(100)') AS Inv,
COMMENT.value('/COMMENTS[1]/COMMENT[3]','varchar(100)') AS Cus,
COMMENT.value('/COMMENTS[1]/COMMENT[4]','varchar(100)') AS Br
FROM Split_Names