我有表呼叫学生,它有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
答案 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