我需要从CSV字符串和最大计数开始生成序列。 当序列超过时,我需要再次启动序列并继续直到我使COUNT变量饱和
我有以下CSV:
A,B,C,D
为了从这个CSV中获取4行,我使用XML和以下语句:
SET @xml_csv = N'<root><r>' + replace('A, B, C, D',',','</r><r>') + '</r></root>'
SELECT
REPLACE(t.value('.','varchar(max)'), ' ', '') AS [delimited items]
FROM
@xml_csv.nodes('//root/r') AS a(t)
现在我的SELECT返回以下输出:
|-------------|
| A |
| B |
| C |
| D |
假设我将@count变量设置为9,我需要输出以下内容:
|--|-----------|
|1 |A |
|2 |B |
|3 |C |
|4 |D |
|5 |A |
|6 |B |
|7 |C |
|8 |D |
|9 |A |
我试图加入一个名为master的表.. [spt_values]但我得到一个COUNT = 10 10行A,10行B等等,而我需要序列有序并重复直到它饱和
答案 0 :(得分:2)
基本上你是在正确的道路上。将分割结果与数字表连接将获得正确的输出。
我选择使用不同的功能来分割csv数据,因为它也使用数字表进行分割。 (取自this great article)
首先,如果您还没有数字表,请创建一个。这是我链接到的文章中使用的脚本:
SET NOCOUNT ON;
DECLARE @UpperLimit INT = 1000;
WITH n AS
(
SELECT
x = ROW_NUMBER() OVER (ORDER BY s1.[object_id])
FROM sys.all_objects AS s1
CROSS JOIN sys.all_objects AS s2
CROSS JOIN sys.all_objects AS s3
)
SELECT Number = x
INTO dbo.Numbers
FROM n
WHERE x BETWEEN 1 AND @UpperLimit;
GO
CREATE UNIQUE CLUSTERED INDEX n ON dbo.Numbers(Number)
WITH (DATA_COMPRESSION = PAGE);
GO
然后,创建拆分功能:
CREATE FUNCTION dbo.SplitStrings_Numbers
(
@List NVARCHAR(MAX),
@Delimiter NVARCHAR(255)
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
(
SELECT Item = SUBSTRING(@List, Number,
CHARINDEX(@Delimiter, @List + @Delimiter, Number) - Number)
FROM dbo.Numbers
WHERE Number <= CONVERT(INT, LEN(@List))
AND SUBSTRING(@Delimiter + @List, Number, LEN(@Delimiter)) = @Delimiter
);
GO
下一步:使用数字表加入拆分结果:
DECLARE @Csv varchar(20) = 'A,B,C,D'
SELECT TOP 10 Item
FROM dbo.SplitStrings_Numbers(@Csv, ',')
CROSS JOIN Numbers
ORDER BY Number
输出:
Item
----
A
B
C
D
A
B
C
D
A
B
非常感谢Aaron Bertrand分享他的知识。