SQL 服务器 - 获取从加入的月份和年份到当前月份的所有月份和年份数字

SQL Server - Get All Month and Year numbers till current month from the Month and Year of joining

我有员工加入日期,从加入日期到我想打印月份和年份数字的日期。

比如员工在2020年7月入职,我需要获取如下数据

MonthNumber YearNumber
    7          2020
    8          2020
    9          2020
    10         2020
    11         2020
    12         2020
     1         2021

下面是我的查询,我正在使用 CTE 并尝试增加它..

DECLARE @JoiningDate Date

SET @JoiningDate = '2020-07-04 11:21:03.827'

;With MonthYears as (
SELECT monthNumber = DATEPART(m, @JoiningDate),
       yearNumber = DATEPART(YEAR, DATEADD(m, i+1, @JoiningDate),
       i = 0

UNION ALL

SELECT monthNumber = DATEPART(m, DATEADD(m, i+1, @JoiningDate)),
       yearNumber = DATEPART(YEAR, DATEADD(m, i+1, @JoiningDate)),
       i = i+1
FROM MonthYears
WHERE DATEPART(m, DATEADD(m, i+1, @JoiningDate)) <= DATEPART(m, GETDATE())
AND DATEPART(year, DATEADD(m, i+1, @JoiningDate)) <= DATEPART(year, GETDATE())
)
SELECT * FROM MonthYears

但是我只能看到1条记录,即加入的月份和年份是7, 2020

您的查询的问题是 WHERE 条件

WHERE DATEPART(m, DATEADD(m, i+1, @JoiningDate)) <= DATEPART(m, GETDATE())
AND DATEPART(year, DATEADD(m, i+1, @JoiningDate)) <= DATEPART(year, GETDATE())

第二次迭代时,Aug - 8不小于DATEPART(m, GETDATE()) = 1

我会在递归 CTE 中使用月份的第一天并增加 1 个月。然后在结果

上使用DATEPART()
DECLARE @JoiningDate Date

SET @JoiningDate = '2020-07-04 11:21:03.827'

;With MonthYears as 
(
    SELECT [FirstOfMonth]   = DATEADD(MONTH, DATEDIFF(MONTH, 0, @JoiningDate), 0)

    UNION ALL

    SELECT  [FirstOfMonth]  = DATEADD(MONTH, 1, [FirstOfMonth])
    FROM    MonthYears
    WHERE   [FirstOfMonth]  < DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0)
)
SELECT  *, 
        monthNumber = DATEPART(month, [FirstOfMonth]),
        yearNumber  = DATEPART(YEAR, [FirstOfMonth])
FROM    MonthYears

你把要求复杂化了。
您所需要的只是每个月的第一天的日期,您可以通过从 @JoiningDate 月份的第一天开始并递归地添加 1 个月来获取它们:

DECLARE @JoiningDate Date;
SET @JoiningDate = '2020-07-04 11:21:03.827';

WITH cte as (
  SELECT DATEFROMPARTS(YEAR(@JoiningDate), MONTH(@JoiningDate), 1) date
  UNION ALL
  SELECT DATEADD(m, 1, date)
  FROM cte
  WHERE DATEADD(m, 1, date) <= GETDATE()
)
SELECT MONTH(date) MonthNumber, 
       YEAR(date) YearNumber 
FROM cte
OPTION (MAXRECURSION 0) -- you may need this because there may exist employees with more than 100 months of employement

参见demo
结果:

> MonthNumber | YearNumber
> ----------: | ---------:
>           7 |       2020
>           8 |       2020
>           9 |       2020
>          10 |       2020
>          11 |       2020
>          12 |       2020
>           1 |       2021