Postgresql生成间隔'15分钟'大于29092个项目系列

yk9xbfzb  于 2022-12-03  发布在  PostgreSQL
关注(0)|答案(1)|浏览(107)

苏特:

create table meter.materialized_quarters
(
    id int4 not null generated by default as identity,
    tm timestamp without time zone
    ,constraint pk_materialized_quarters primary key (id)
    --,constraint uq_materialized_quarters unique (tm) 
);

然后设置数据:

insert into meter.materialized_quarters (tm) 
select GENERATE_SERIES ('1999-01-01', '2030-10-30', interval '15 minute');

并检查数据:

select count(*),tm 
    from meter.materialized_quarters 
    group by tm  
    having count(*)> 1

一些结果:

count|tm                     |
-----+-----------------------+
    2|1999-10-31 02:00:00.000|
    2|1999-10-31 02:15:00.000|
    2|1999-10-31 02:30:00.000|
    2|1999-10-31 02:45:00.000|
    2|2000-10-29 02:00:00.000|
    2|2000-10-29 02:15:00.000|
    2|2000-10-29 02:30:00.000|
    2|2000-10-29 02:45:00.000|
    2|2001-10-28 02:00:00.000|
    2|2001-10-28 02:15:00.000|
    2|2001-10-28 02:30:00.000|

....

详细信息:

select * from meter.materialized_quarters where tm = '1999-10-31 01:45:00';

结果:

id   |tm                     |
-----+-----------------------+
29092|1999-10-31 01:45:00.000|

如我所见,29092是由以下项生成的最大非重复数据系列:GENERATE_SERIES,间隔15分钟,1999年到2030年的表(表.物化_季度)如何填写?
一种解决方案是:
插入到计数器中。materialized_quartters(tm)选择GENERATE_SERIES(“1999 -01- 01”,“1999-10-31 01:45:00”,间隔“15分钟”);
然后:
插入到计数器中。物化季度(tm)选择GENERATE_SERIES(“1999 -10-31 02:00:00.000”,“2000-10-29 00:00:00.000”,间隔“15分钟”);
一次又一次。
或者

with bad as (
    select count(*),tm
    from meter.materialized_quarters 
    group by tm  
    having count(*)> 1
) 
, ids as (
    select mq1.id, mq2.id as iddel
    from meter.materialized_quarters mq1 inner join bad on bad.tm = mq1.tm inner join meter.materialized_quarters mq2 on bad.tm = mq2.tm 
    where mq1.id<mq2.id
)
delete from meter.materialized_quarters
where id in (select iddel from ids);

还有更“优雅”的方式吗?
编辑。我看到问题了。xxxx-10-29 02:00:00 -夏季时间变成冬季时间。
选择生成系列(“1999 -10-31 01:45:00”,“1999-10-31 02:00:00”,间隔“15分钟”);

0s0u357o

0s0u357o1#

您的问题是从generate_series()返回的timestamp WITH time zone与定义为timestamp WITHOUT time zone的列之间的转换。
1999-10-31是夏令时更改的日期(至少在某些国家/地区)
如果将列更改为timestamp WITH time zone,则代码无需任何修改即可正常工作。
Example
如果要继续使用timestamp WITHOUT timestamp,则需要转换generate_series()返回的值

insert into materialized_quarters (tm) 
select g.tm at time zone 'UTC' --<< change to the time zone you need
from GENERATE_SERIES ('1999-01-01', '2030-10-30', interval '15 minute') as g(tm)

Example

相关问题