我发布的问题非常类似,并在SQL How to Split One Column into Multiple Variable Columns
回答在我的情况下,我有一列数据用2种类型的分隔符分隔(我知道,很糟糕)。以下是一些代码:
create table #MessyDelim
(DelimList varchar(255));
insert into #MessyDelim
Values ('30;120;100')
, ('50;60')
, ('75/10')
, ('115/50/20/10/5')
, ('80;65;40;23;12;10')
, ('100')
我的目标是使用函数或CTE分别返回这些值。理想情况下,我希望它们在单独的列中返回(列数必须动态确定)。
这是所需的输出:
DL1 DL2 DL3 DL4 DL5 DL6
50 60
75 10
115 50 20 10 5
80 65 40 23 12 10
100
答案 0 :(得分:1)
我喜欢一个好的谜题。
;WITH
MessyDelim AS --As Nenad Zivkovic suggested, standardize on one delimiter for simplicity
( SELECT DelimList,REPLACE(DelimList,'/',';') AS String
FROM #MessyDelim),
Split AS --Recursive CTE to produce strings each with one less delimited value attached
( SELECT DelimList, 1 AS Sort, String + ';' AS String
FROM MessyDelim
UNION ALL
SELECT DelimList, Sort+1, RIGHT(String,LEN(String)-CHARINDEX(';',String))
FROM Split
WHERE CHARINDEX(';',String) > 0 ),
Cleanup AS --Reduce strings to single delimited value each
( SELECT DelimList,LEFT(String,CHARINDEX(';',String)-1) AS String, Sort
FROM Split
WHERE String <> '' )
SELECT DelimList, --Pivot out into columns
[1] AS DL1,
[2] AS DL2,
[3] AS DL3,
[4] AS DL4,
[5] AS DL5,
[6] AS DL6
FROM Cleanup
PIVOT(MAX(String) FOR Sort IN ([1],[2],[3],[4],[5],[6])) pvt
ORDER BY DelimList
OPTION (MAXRECURSION 10) --Just for safety sake
答案 1 :(得分:1)
这是完整的动态SQL动态生成列。
;WITH
MessyDelim AS --As Nenad Zivkovic suggested, standardize on one delimiter for simplicity
( SELECT DelimList,REPLACE(DelimList,'/',';') AS String
FROM #MessyDelim),
Split AS --Recursive CTE to produce strings each with one less delimited value attached
( SELECT DelimList, 1 AS Sort, String + ';' AS String
FROM MessyDelim
UNION ALL
SELECT DelimList, Sort+1, RIGHT(String,LEN(String)-CHARINDEX(';',String))
FROM Split
WHERE CHARINDEX(';',String) > 0 )
--Reduce strings to single delimited value each, and store in table
SELECT DelimList,LEFT(String,CHARINDEX(';',String)-1) AS String, Sort
INTO #CleanDelim
FROM Split
WHERE String <> ''
OPTION (MAXRECURSION 10)
--Produce dynamic list of column names and alias for SELECT list
DECLARE @Cols AS VARCHAR(MAX)
SELECT @Cols = STUFF((SELECT DISTINCT '],[' + CAST(Sort AS VARCHAR) + '] AS [DL' + CAST(Sort AS VARCHAR)
FROM #CleanDelim
ORDER BY '],[' + CAST(Sort AS VARCHAR) + '] AS [DL' + CAST(Sort AS VARCHAR)
FOR XML PATH('')),1,2,'') + ']'
--Produce dynamic list of column names for PIVOT clause
DECLARE @List AS VARCHAR(MAX)
SELECT @List = STUFF((SELECT DISTINCT '],[' + CAST(Sort AS VARCHAR)
FROM #CleanDelim
ORDER BY '],[' + CAST(Sort AS VARCHAR)
FOR XML PATH('')),1,2,'') + ']'
--Generate dynamic query
DECLARE @SQL AS VARCHAR(MAX)
SELECT @SQL = '
SELECT DelimList,' + @Cols + '
FROM #CleanDelim
PIVOT(MAX(String) FOR Sort IN (' + @list + ')) pvt'
FROM #CleanDelim
--Execute dynamic query
EXEC(@SQL)