将日期范围列转换为月

时间:2020-07-21 16:38:55

标签: sql sql-server rdbms

我有表呼叫学生,它有3列ID,DateFrom,DateTo,现在我想将两个Dates列(范围从Datefrom和Dateto转换为一列月份)作为输出。

表结构如下。日期格式(yyyy-mm-dd)

ID  DateFrom    DateTo

123 2019-12-03  2020-02-03

456 2020-02-03  2020-02-21

输出结构

ID  Months

123 2019-12

123 2020-01

123 2020-02

456 2020-02

2 个答案:

答案 0 :(得分:0)

假设您的表格称为“ dataval” 试试这个

;WITH minmax AS (
     SELECT Min(Eomonth(datefrom)) AS MinDate, 
            Max(Eomonth(dateto))   AS MaxDate 
     FROM   dataval), 
 months (date) AS (
     SELECT mindate 
     FROM   minmax 
     UNION ALL 
     SELECT Dateadd(month, 1, date) 
     FROM   months 
     WHERE  Dateadd(month, 1, date) <= (SELECT maxdate FROM minmax)) 
 SELECT ID, FORMAT (date, 'yyyy-MM') Months 
 FROM   dataval 
 INNER JOIN months 
    ON months.date BETWEEN Eomonth(dataval.datefrom) AND Eomonth(dataval.dateto) 

提琴here

答案 1 :(得分:0)

最简单的方法是使用辅助日历表-在两个表之间进行简单的连接:

select distinct a.id, convert(char(7), b.[Date], 120) as month
from yourTable as a
join Calendar as b
    on a.DateFrom <= b.[Date]
    and a.DateTo >= b.[Date]
;

如果没有日历表,则可能要考虑添加一个。

如果您不能(或不想)添加日历表,则可以使用数字(计数)表获得相同的结果。
如果您没有统计表,则可以使用公用表表达式即时生成一个统计表。

在这种情况下,SQL的外观如下:

WITH N10 AS
(
    SELECT n
    FROM (VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9))V(n)
), Tally AS
(
    SELECT TOP (SELECT MAX(DATEDIFF(MONTH, DateFrom, DateTo)) + 1 FROM yourTable) ROW_NUMBER() OVER(ORDER BY @@SPID) -1 As n
    FROM N10 As Ten
    CROSS JOIN N10 As Hundred
    --CROSS JOIN N10 As Thousand
)

SELECT [ID], CONVERT(char(7), Months, 120) As Months
FROM yourTable
CROSS APPLY 
(
    SELECT N, DATEADD(MONTH, N, [DateFrom]) As Months
    FROM Tally 
) X
WHERE Months <= EOMONTH([DateTo])
ORDER BY Id, Months