使用SQL Server 2016。
我有下表
[ID] [Name List1] [Name List2] [Name List3]
1 a1,a2,a3 a21,a22 a31,a32,a33,a34,a45
2 b1,b2 b21,b22,b23,b24 b31
3 etc....
[ID]是唯一的标识符列。
我需要将所有这些用逗号分隔的字段拆分为单独的记录。
我到目前为止所做的:
SELECT a.*, b.[Name List1] FROM [TABLE1] a LEFT JOIN
(SELECT DISTINCT [ID], value AS [Name List1]
FROM [TABLE1] CROSS APPLY STRING_SPLIT([Name List1], ',')
WHERE value IS NOT NULL AND rtrim(value) <> '') b ON a.[ID]=b.[ID]
此查询将基于第一列(即[名称列表1])拆分记录 但是我需要对所有列([Name List2]和[Name List3]都这样做)。
是否有一种优雅的方法可以用最少的编码来实现它?
所需结果应包括这些逗号分隔值的所有可能组合:
[ID] [Name List1] [Name List2] [Name List3]
1 a1 a21 a31
2 a2 a21 a31
3 a3 a21 a31
4 etc... meaning all possible combination of column splits
答案 0 :(得分:1)
如果要获取所有可能的组合,请使用STRING_SPLIT()
和三个CROSS APPLY
运算符:
输入:
CREATE TABLE #Data (
ID int,
[Name List1] varchar(100),
[Name List2] varchar(100),
[Name List3] varchar(100)
)
INSERT INTO #Data
(ID, [Name List1], [Name List2], [Name List3])
VALUES
(1, 'a1,a2,a3', 'a21,a22', 'a31,a32,a33,a34,a45'),
(2, 'b1,b2', 'b21,b22,b23,b24', 'b31')
T-SQL:
SELECT
d.ID,
s1.[value] AS [Name List1],
s2.[value] AS [Name List2],
s3.[value] AS [Name List3]
FROM #Data d
CROSS APPLY STRING_SPLIT(d.[Name List1], ',') s1
CROSS APPLY STRING_SPLIT(d.[Name List2], ',') s2
CROSS APPLY STRING_SPLIT(d.[Name List3], ',') s3
输出:
ID Name List1 Name List2 Name List3
1 a1 a21 a31
1 a1 a21 a32
1 a1 a21 a33
1 a1 a21 a34
1 a1 a21 a45
1 a1 a22 a31
1 a1 a22 a32
1 a1 a22 a33
1 a1 a22 a34
1 a1 a22 a45
…
如果要获取每个子串位置的所有可能组合,则STRING_SPLIT()
在这里不是选项,因为此函数返回包含所有子串的表,但是它们没有顺序,并且子串的顺序为不保证。在这种情况下,一种选择是使用JSON
将文本转换为有效的REPLACE()
数组,然后在默认模式下使用OPENJSON()
将JSON
数组作为表检索,该数组具有列key
,value
和type
(key
列包含指定数组中元素的索引)。
T-SQL:
SELECT
d.ID,
j1.[key] + 1 AS [Key List1], j1.[value] AS [Name List1],
j2.[key] + 1 AS [Key List2], j2.[value] AS [Name List2],
j3.[key] + 1 AS [Key List3], j3.[value] AS [Name List3]
FROM #Data d
CROSS APPLY OPENJSON('["' + REPLACE(d.[Name List1], ',', '","') + '"]') j1
CROSS APPLY OPENJSON('["' + REPLACE(d.[Name List2], ',', '","') + '"]') j2
CROSS APPLY OPENJSON('["' + REPLACE(d.[Name List3], ',', '","') + '"]') j3
输出:
ID Key List1 Name List1 Key List2 Name List2 Key List3 Name List3
1 1 a1 1 a21 1 a31
1 1 a1 1 a21 2 a32
1 1 a1 1 a21 3 a33
1 1 a1 1 a21 4 a34
1 1 a1 1 a21 5 a45
1 1 a1 2 a22 1 a31
1 1 a1 2 a22 2 a32
1 1 a1 2 a22 3 a33
1 1 a1 2 a22 4 a34
1 1 a1 2 a22 5 a45
…