包含月份

时间:2016-08-23 15:42:16

标签: sql postgresql generate-series

有一张表dates_calendar

 id | date
 -------------------------
 13 | 2016-10-23 00:00:00
 14 | 2016-10-24 00:00:00

我需要更新此表并插入日期,直到下个月从表中的最后一个日期算起。例如。最后日期为2016-10-24 00:00:00 - 我需要在2016-10-31之前插入日期。之后(现在的最后一个日期是2016-10-31)下一个语句调用应该插入日期到2016-11-30,依此类推。

我的SQL代码示例,但它一直会插入30天。

INSERT INTO dates_calendar (date)
    VALUES (
      generate_series(
        (SELECT date FROM dates_calendar ORDER BY date DESC LIMIT 1) + interval '1 day',
        (SELECT date FROM dates_calendar ORDER BY date DESC LIMIT 1) + interval '1 month',
        '1 day'
      )
    );

我正在使用PostgreSQL。也可以去除上一个日期的重复SELECT语句。

3 个答案:

答案 0 :(得分:1)

要计算您需要插入的第一个和最后一个日期,您可以使用此查询:

select max(date) + interval '1' day as first_day, 
       date_trunc('month', max(date) + interval '1' month) - interval '1' day as last_day
from dates_calendar

表达式date_trunc('month', max(date) + interval '1' month)计算 next 月的开始日期。从那里减去一天会给你那个月的最后一天。

然后可以使用它来生成日期列表:

with from_to (first_day, last_day) as (
  select max(date) + interval '1' day, 
         date_trunc('month', max(date) + interval '1' month) - interval '1' day
  from dates_calendar
)
select dt
from generate_series(  (select first_day from from_to), (select last_day from from_to), interval '1' day) as t(dt);

最后,这可用于将生成的行插入表中:

with from_to (first_day, last_day) as (
  select max(date) + interval '1' day, 
         date_trunc('month', max(date) + interval '1' month) - interval '1' day
  from dates_calendar
)
insert into dates_calendar (date)
select dt
from generate_series(  (select first_day from from_to), (select last_day from from_to), interval '1' day) as t(dt);

答案 1 :(得分:1)

insert into dates_calendar (date)
select dates::date
from (
    select max(date)::date+ 1 next_day, '1day'::interval one_day, '1month'::interval one_month
    from dates_calendar
    ) s,
    generate_series(
        next_day, 
        date_trunc('month', next_day)+ one_month- one_day, 
        one_day) dates;

答案 2 :(得分:0)

with max_date (d) as (select max(date)::date from dates_calendar)
insert into dates_calendar (date)
select d
from generate_series (
    (select d from max_date) + 1,
    (select date_trunc('month', d + interval '1 month')::date - 1 from max_date),
    '1 day'
) g(d)