如何在Postgresql中生成从开始日期到now()之间的月份

时间:2018-10-05 14:11:53

标签: postgresql

我还有一个问题,如何使代码块在堆栈溢出时起作用,但这是一个附带问题。

我有这个有效的准代码:

select
    * 
from 
    unnest('{2018-6-1,2018-7-1,2018-8-1,2018-9-1}'::date[],
           '{2018-6-30,2018-7-31,2018-8-31,2018-9-30}'::date[] 
    ) zdate(start_date, end_date)
left join lateral pipe_f(zdate...

但是现在我希望它从2018年6月1日到now()工作。最好的方法是什么?

哦,PostgreSQL 10.是的!

2 个答案:

答案 0 :(得分:2)

您的查询提供了从“ 2018-06-01”到现在的月份的第一天和最后几天的列表。因此,我假设您想以更动态的方式做到这一点:


demo: db<>fiddle

SELECT
    start_date,
    (start_date + interval '1 month -1 day')::date as end_date
FROM (
    SELECT generate_series('2018-6-1', now(), interval '1 month')::date as start_date
)s 

结果

start_date  end_date
2018-06-01  2018-06-30
2018-07-01  2018-07-31
2018-08-01  2018-08-31
2018-09-01  2018-09-30
2018-10-01  2018-10-31

generate_series(timestamp, timestamp, interval)生成时间戳列表。从“ 2018-06-01”开始,直到now()(间隔为1个月),都会显示以下信息:

start_date
2018-06-01 00:00:00+01
2018-07-01 00:00:00+01
2018-08-01 00:00:00+01
2018-09-01 00:00:00+01
2018-10-01 00:00:00+01

使用::date强制转换将这些时间戳转换为日期。

然后我添加1个月以获得下个月。但是,由于我们对上个月的最后一天感兴趣,因此我再次减去了一天(+ interval '1 month -1 day'

答案 1 :(得分:1)

另一种更符合ANSI标准的选项是使用递归CTE:

WITH RECURSIVE
    dates(d) AS
    (
        SELECT '2018-06-01'::TIMESTAMP
        UNION ALL
        SELECT d + INTERVAL '1 month'
        FROM dates 
        WHERE d + INTERVAL '1 month' <= '2018-10-01'
    )
SELECT 
    d AS start_date, 
    -- add 1 month, then subtract 1 day, to get end of current month
    (d + interval '1 month') - interval '1 day' AS end_date
FROM dates