如何显示两个日期之间的日期,但重复表中的其他字段?
CREATE TABLE MiTabla(
id int,
tipo int,
fecha1 date,
fecha2 date
)
INSERT INTO MiTabla VALUES
(1000,1,'2019-05-31','2019-07-31'),
(1001,2,'2019-06-30','2017-10-31')
我的结果应该是:
id tipo fecha1 fecha2 fecha3
1000 1 '2019-05-31' '2019-07-31' '2019-05-31'
1000 1 '2019-05-31' '2019-07-31' '2019-06-30'
1000 1 '2019-05-31' '2019-07-31' '2019-07-31'
1001 2 '2019-06-30' '2019-10-31' '2019-06-30'
1001 2 '2019-06-30' '2019-10-31' '2019-07-31'
1001 2 '2019-06-30' '2019-10-31' '2019-08-31'
1001 2 '2019-06-30' '2019-10-31' '2019-09-30'
1001 2 '2019-06-30' '2019-10-31' '2019-10-31'
答案 0 :(得分:2)
创建一个包含月份数字的帮助表。
CREATE TABLE Months(
id int
);
INSERT INTO Months VALUES
(1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12);
然后您可以执行以下查询:
SELECT t.id, t.tipo, t.fecha1, t.fecha2, dateadd(month, m.id - MONTH(fecha2), fecha2) AS fecha3
FROM
MiTabla t
INNER JOIN Months m
ON m.id BETWEEN MONTH(fecha1) AND MONTH(fecha2)
在此处查看结果:http://sqlfiddle.com/#!18/4ac6f/3/0
您也可以使用
SELECT t.id, t.tipo, t.fecha1, t.fecha2, dateadd(month, m.id - MONTH(fecha1), fecha1) AS fecha3
FROM
MiTabla t
INNER JOIN Months m
ON m.id BETWEEN MONTH(fecha1) AND MONTH(fecha2)
但是10月的日期将是30天,因为月份被添加到6月30日。如果参考日期的日期是30天,则使用这两种变体您将获得30。如果您的日期始终代表月末,则最好使用下个月的第一天,然后减去1天。
-- This assumes that the dates always represent end of months.
SELECT
t.id, t.tipo, t.fecha1, t.fecha2,
dateadd(day, -1, dateadd(month, m.id - MONTH(fecha1), dateadd(day, 1, fecha1))) AS fecha3
FROM
MiTabla t
INNER JOIN Months m
ON m.id BETWEEN MONTH(fecha1) AND MONTH(fecha2)
对fecha3
的表达式进行了解释(从最嵌套的部分开始阅读):
dateadd(day, -1, -- Subtract one day from 1st of next month to get last day of month.
dateadd(month, m.id - MONTH(fecha1), -- creates the months between 1st+1 and last+1.
dateadd(day, 1, fecha1) -- gets 1st day of next month.
)
) AS fecha3
http://sqlfiddle.com/#!18/f7d5fc/3/0
但是请注意,这仅在所有涉及的月份都在同一年内时有效。
答案 1 :(得分:0)
递归CTE对此非常有用。
WITH RCTE AS
(
SELECT id, tipo, fecha1, fecha2
, EOMONTH(fecha1) AS fecha3
FROM MiTabla
UNION ALL
SELECT id, tipo, fecha1, fecha2
, EOMONTH(DATEADD(day,1,fecha3))
FROM RCTE
WHERE fecha3 < fecha2
)
SELECT *
FROM RCTE
ORDER BY 1, 2, 3;