Sql server 为0和之间的每个整数插入行,不带光标

Sql server 为0和之间的每个整数插入行,不带光标,sql-server,tsql,Sql Server,Tsql,我有一个id和计数的源表 id count a 5 b 2 c 31 我需要用每个整数填充目标表,直到每个id的计数 id value a 1 a 2 a 3 a 4 a 5 b 1 b 2 c 1 c 2 etc... 我目前的解决方案如下: INSERT INTO destination (id,value) source.id sequence.number FROM (V

我有一个id和计数的源表

id count
a     5
b     2
c     31
我需要用每个整数填充目标表,直到每个id的计数

id value
a     1
a     2
a     3
a     4
a     5
b     1
b     2
c     1
c     2
etc...
我目前的解决方案如下:

INSERT INTO destination (id,value)
    source.id
    sequence.number
FROM 
(VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9)) AS sequence(number)
INNER JOIN 
source ON sequence.number <= source.count

这个解决方案有一个上限,而且很简单。是否有办法用一组整数替换序列?或者其他不使用循环的解决方案。

不幸的是,SQL Server中没有所有整数的集合。但是,使用一些技巧,您可以轻松生成这样一组:

select N from (
    select ROW_NUMBER() OVER (ORDER BY t1.object_id) AS N 
    from sys.all_objects t1, sys.all_objects t2
) AS numbers
where N between 1 and 1000000
将生成一组从1到1000000的所有数字。如果需要几百万个以上的数字,请第三次将sys.all_对象添加到交叉联接中。

这应该可以:

 WITH r AS (
    SELECT id, count, 1 AS n FROM SourceTable
    UNION ALL
    SELECT id, count, n+1 FROM r WHERE n<count
)
SELECT id,n FROM r
order by id,n
OPTION (MAXRECURSION 0)

您可以在本页中找到许多示例:

DECLARE @table TABLE (ID VARCHAR(1), counter INT)

INSERT INTO @table SELECT 'a', 5
INSERT INTO @table SELECT 'b', 3
INSERT INTO @table SELECT 'c', 31



;WITH cte (ID, counter) AS (

    SELECT id, 1
    FROM @table 
    UNION ALL
    SELECT c.id, c.counter +1
    FROM cte AS c
    INNER JOIN @table AS t
        ON t.id = c.id
    WHERE c.counter + 1 <= t.counter

)
SELECT *
FROM cte
ORDER BY ID, Counter

无技巧,基于集合/计算,只生成所需值的整数。