while 循环函数 union 函数结束

While loop function union function end

我想循环下面显示的代码。我想在可变年限内使用 [getpublicholidays] 函数并将它们合并(并集)。不幸的是,我不知道如何在联合循环中使用该函数。有人可以帮忙吗?

select  * from [getpublicholidays](2019)
UNION
select  * from [getpublicholidays](2020)
UNION
select  * from [getpublicholidays](2021)
UNION
select  * from [getpublicholidays](2022)

如果你循环 X 年,每次循环到新的一年,你就不需要联合其他年份。相反,您需要在某个地方存储一年到下一年的结果。也许您正在寻找这样的东西,我只是在为您的函数输出创建列,因为我不知道它们到底是什么...相应地进行调整...

--Create a temp table to match the results of the output of the function. 
IF OBJECT_ID('tempdb.dbo.#publicHolidays') IS NOT NULL
    DROP TABLE #publicHolidays

    CREATE TABLE #publicHolidays(Holiday VARCHAR(28), HolidayYear INT, HolidayDate DATETIME)

--Set a variable for how many years back to include
DECLARE @NumberOfYears INT = 4

--Loop through each year
WHILE @NumberOfYears > 0
BEGIN
    
    DECLARE @Year INT =  (SELECT YEAR(GetDate()) - @NumberOfYears +1) --Remove +1 to not include current year
    
    INSERT INTO #publicHolidays (Holiday, HolidayYear, HolidayDate)
    SELECT * FROM getpublicholidays(@Year)   

    SET @NumberOfYears -= 1
END

--Table now has results from each of the 4 years
SELECT * FROM #publicHolidays

IF OBJECT_ID('tempdb.dbo.#publicHolidays') IS NOT NULL
    DROP TABLE #publicHolidays

如果这不能满足您的需求,那么我们确实需要有关您所追求的内容的更多详细信息。

您不需要循环、递归或临时 tables.

只需使用虚拟 table 即可,CROSS APPLY 您的函数

SELECT *
FROM (VALUES
  (2019),
  (2020),
  (2021),
  (2022)
) AS Years(Year)
CROSS APPLY getpublicholidays(Years.Year);

如果你想要可变的行数,你可以使用数字table的虚拟

WITH L0 AS (
    SELECT n
    FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1) ) AS v(n)
),
L1 AS (
    SELECT n = 1
    FROM L0 AS a, L0 AS b
)
SELECT *
FROM (
    SELECT TOP (@endYear - @startYear + 1)
      @startYear - 1 + ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
    FROM L0
) AS Years(Year)
CROSS APPLY getpublicholidays(Years.Year);

鉴于年份通常只有少量行,您可以 hard-code 一个固定数字,然后加入

SELECT *
FROM (VALUES
    (2010),(2011),(2012),(2013),(2014),(2015),(2016),(2017),(2018),(2019),
    (2020),(2021),(2022),(2023),(2024),(2025),(2026),(2027),(2028),(2029),
    (2030),(2031),(2032),(2033),(2034),(2035),(2036),(2037),(2038),(2039)
) AS Years(Year)
CROSS APPLY getpublicholidays(Years.Year);