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

时间:2021-01-09 09:52:38

标签: sql-server common-table-expression

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

例如员工在 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

2 个答案:

答案 0 :(得分:0)

您查询的问题在于 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

答案 1 :(得分:0)

您正在使要求复杂化。
您所需要的只是每个月的第一天的日期,您可以通过从 @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