在没有循环和游标

时间:2018-01-04 09:50:46

标签: sql sql-server

我有一个临时表,我需要插入两个日期范围之间的所有年份。例如,如果日期范围是从2010年到2018年,那么表格将具有

2010
2011
2012
2013
2014
2015
2016
2017
2018

任何人都有任何查询,我可以在不使用while循环或游标的情况下将这些值插入到临时表中。

4 个答案:

答案 0 :(得分:4)

使用递归CTE。喜欢这个

DECLARE @Min INT=2010,@Max INT=2018
;WITH CTE
AS
(
    SELECT
        MyData = @MIn

    UNION ALL

    SELECT
        MyData = MyData+1
        FROM CTE
            WHERE MyData < @Max
)
SELECT
    *
    FROM CTE

结果

enter image description here

答案 1 :(得分:1)

另一个选项是ad-hoc计数表

Declare @R1 int = 2010
Declare @R2 int = 2018

Select Top (@R2-@R1+1) 
       N=@R1-1+Row_Number() Over (Order By (Select NULL)) 
 From  master..spt_values n1

答案 2 :(得分:0)

您可以使用计数表或CTE,如:

DECLARE @MinYear AS INT = 2010;
DECLARE @MaxYear AS INT = 2018;
WITH NumbersCTE
AS
(
    SELECT ROW_NUMBER() OVER (ORDER BY Num1.Num) -1 As Num
    from (VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) AS Num1(num)
    CROSS JOIN 
        (VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10)) AS Num2(num)

)
SELECT @MinYear + Num
FROM NumbersCTE
WHERE @MinYear + Num <= @MaxYear

答案 3 :(得分:0)

尝试:这也是使用GOTO

的另一种方式
CREATE TABLE #EData(Edata INT)

DECLARE @Min INT=2010, @Max INT=2018, @curValue INT

GenerateNumber:

SELECT @curValue = MAX(EData) FROM #EData
INSERT INTO #EData
SELECT ISNULL(@curValue, @Min-1)+1

IF (SELECT MAX(EData) FROM #Edata) < @Max
GOTO GenerateNumber

SELECT * FROM #EData

<强>输出

Edata
-----
2010
2011
2012
2013
2014
2015
2016
2017
2018