如何显示两个日期之间的日期

时间:2019-11-29 20:37:16

标签: sql-server tsql

如何显示两个日期之间的日期,但重复表中的其他字段?

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'

2 个答案:

答案 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;