SELECT A.Name, A.Times
FROM (VALUES
('John', 1)
, ('Paul', 2)
, ('George', 3)
, ('Ringo', 1)
) A (Name, Times)
CROSS APPLY(VALUES
(1), (2), (3)
) B (n)
WHERE A.Times >= B.n
ORDER BY A.Name;
我能想到的唯一缺点是您必须手动输入数字,但这可以通过数字表/TVF 轻松解决:
SELECT A.Name, A.Times
FROM (VALUES
('John', 1)
, ('Paul', 2)
, ('George', 3)
, ('Ringo', 1)
) A (Name, Times)
CROSS APPLY dbo.RangeSmallInt(1, A.Times) B;
我还在评论中注意到您遇到了 sys.objects 的限制,并且有人发布了生成序列的精彩链接。我的示例中使用的 RangeSmallInt 函数基于该帖子,并且非常高效。这是代码:
-- Generate a range of up to 65,536 contiguous BIGINTS
CREATE FUNCTION dbo.RangeSmallInt (
@n1 BIGINT = NULL
, @n2 BIGINT = NULL
)
RETURNS TABLE
AS
RETURN (
WITH Numbers AS (
SELECT N FROM(VALUES
(1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 16
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 32
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 48
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 64
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 80
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 96
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 112
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 128
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 144
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 160
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 176
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 192
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 208
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 224
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 240
, (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1), (1) -- 256
) V (N)
)
SELECT TOP (
CASE
WHEN @n1 IS NOT NULL AND @n2 IS NOT NULL THEN ABS(@n2 - @n1) + 1
ELSE 0
END
)
N = ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) - 1 + CASE WHEN @n1 <= @n2 THEN @n1 ELSE @n2 END
FROM Numbers A, Numbers B
WHERE ABS(@n2 - @n1) + 1 < 65537
);
扩展它以支持大小 INT:
-- Generate a range of up to 4,294,967,296 contiguous BIGINTS
CREATE FUNCTION dbo.RangeInt (
@num1 BIGINT = NULL
, @num2 BIGINT = NULL
)
RETURNS TABLE
AS
RETURN (
WITH Numbers(N) AS (
SELECT N
FROM dbo.RangeSmallInt(0, 65535)
)
SELECT TOP (
CASE
WHEN @num1 IS NOT NULL AND @num2 IS NOT NULL THEN ABS(@num1 - @num2) + 1
ELSE 0
END
)
N = ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) + CASE WHEN @num1 <= @num2 THEN @num1 ELSE @num2 END - 1
FROM Numbers A
, Numbers B
WHERE ABS(@num1 - @num2) + 1 < 4294967297
);