我正在尝试使用SQL Server构建一个循环。
当我执行SELECT 1 UNION SELECT 2 UNION SELECT 3;
时,SQL Server会创建一个包含1列和4行的表。
如果不使用UNION
答案 0 :(得分:4)
您可以使用values()
表构造函数:
select *
from (values (1), (2), (3), (4)) v(n);
答案 1 :(得分:3)
您可以使用递归cte轻松完成此操作。
declare @max int=4
;with cte as
(
select 1 as val
union all
select val+1
from cte
where val < @max
)
select *
from cte
答案 2 :(得分:2)
以下是一些常见的选项,以防您的用例扩展数百或数千行...
通常看到一个理货表...
WITH
E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
cteTally(N) AS
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
)
select N from cteTally
或者,使用Jeff Moden的功能
CREATE FUNCTION [dbo].[fnTallyProg]
/**********************************************************************************************************************
Purpose:
Given a start value, end value, and increment, create a sequencial list of integers.
Programmers Notes:
1. The increment can be negative if the start value is greater than the end value. In other words, it can count down
as well as up.
Revison History:
Rev 00 - 18 Feb 2017 - Jeff Moden
- Rewrite original to take start, end, and increment parameters.
**********************************************************************************************************************/
(
@pStart BIGINT
,@pEnd BIGINT
,@pIncrement BIGINT
)
RETURNS TABLE WITH SCHEMABINDING AS
RETURN WITH
E01(N) AS (SELECT NULL FROM (VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))E0(N)) --10 rows
,E04(N) AS (SELECT NULL FROM E01 a CROSS JOIN E01 b CROSS JOIN E01 c CROSS JOIN E01 d) --10 Thousand rows
,E16(N) AS (SELECT NULL FROM E04 a CROSS JOIN E04 b CROSS JOIN E04 c CROSS JOIN E04 d) --10 Quadrillion rows, which is crazy
,Tally(N) AS (SELECT TOP (ABS((@pEnd-@pStart+@pIncrement)/@pIncrement))
N = ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM E16
WHERE (@pStart<=@pEnd AND @pIncrement > 0)
OR (@pStart>=@pEnd AND @pIncrement < 0)
ORDER BY N
)
SELECT TOP (ABS((@pEnd-@pStart+@pIncrement)/@pIncrement))
N = (t.N-1)*@pIncrement+@pStart
FROM Tally t
ORDER BY t.N
;
GO
或者,JL的另一个快速功能
CREATE FUNCTION [dbo].[tfn_Tally]
(
@NumOfRows BIGINT = 1000000
,@StartWith BIGINT = 1563984
)
/* ============================================================================
07/20/2017 JL, Created. Capable of creating a sequense of rows
ranging from -10,000,000,000,000,000 to 10,000,000,000,000,000
============================================================================ */
RETURNS TABLE WITH SCHEMABINDING AS
RETURN
WITH
cte_n1 (n) AS (SELECT 1 FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) n (n)), -- 10 rows
cte_n2 (n) AS (SELECT 1 FROM cte_n1 a CROSS JOIN cte_n1 b), -- 100 rows
cte_n3 (n) AS (SELECT 1 FROM cte_n2 a CROSS JOIN cte_n2 b), -- 10,000 rows
cte_n4 (n) AS (SELECT 1 FROM cte_n3 a CROSS JOIN cte_n3 b), -- 100,000,000 rows
cte_Tally (n) AS (
SELECT TOP (@NumOfRows)
(ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) - 1) + @StartWith
FROM
cte_n4 a CROSS JOIN cte_n4 b -- 10,000,000,000,000,000 rows
)
SELECT
t.n
FROM
cte_Tally t;
答案 3 :(得分:1)
只是为了好玩,您可以使用临时计数表
示例强>
Declare @N int =4
Select Top (@N) N=Row_Number() Over (Order By (Select NULL))
From master..spt_values n1
<强>返回强>
N
1
2
3
4
答案 4 :(得分:1)
如果你需要的是一系列要在以后连接到另一个表的值,我强烈建议创建一个一次性的数字辅助表,如here所述
生成这样的表的代码非常基本:
SELECT TOP (1000000) n = CONVERT(INT, ROW_NUMBER() OVER (ORDER BY s1.[object_id]))
INTO dbo.Numbers
FROM sys.all_objects AS s1 CROSS JOIN sys.all_objects AS s2
OPTION (MAXDOP 1);
CREATE UNIQUE CLUSTERED INDEX n ON dbo.Numbers(n)
这将创造一个持久的&#34;数字&#34;数据库中的表,然后您可以使用它来连接到其他表或使用函数。