选择行数,按 PostgreSQL 中时间间隔的动态范围排序

Posted

技术标签:

【中文标题】选择行数,按 PostgreSQL 中时间间隔的动态范围排序【英文标题】:Select a count of rows, order by dynamic ranges of time intervals in PostgreSQL 【发布时间】:2013-11-29 10:39:00 【问题描述】:

这是我的问题的测试表:

CREATE TABLE document (
    id integer NOT NULL,
    name character varying(120) NOT NULL,
    owner_id bigint DEFAULT 0 NOT NULL,
    doc_type_id smallint DEFAULT 1 NOT NULL,
    archived boolean DEFAULT false NOT NULL,
    insert_date timestamp without time zone DEFAULT now() NOT NULL,
    modify_date timestamp without time zone DEFAULT now() NOT NULL,
    last_writer_id bigint
);

Modify_date 确定某人上次编辑文档的时间。

为了进行一些统计,我需要获取创建(插入日期)和修改日期之间的时间。然后要显示条形图,我需要获取此时间间隔的文档计数,例如,在 0 到 5 天、6 到 10 天等之间。所以我猜想在查询中必须计算范围。 预期的结果(或某种......)是:

Age                Count
0-5                2
6-10               5
11-15              9
...                ...

当然,年龄可以在 0-5 == 0、6-10 == 1 的范围内。我将准备数据以显示它们。

我发现一篇非常相似的帖子,但我无法将其应用于我的案例。 (Select data for 15 minute windows - PostgreSQL)

感谢您能给我带来的任何答案。

编辑 1:

范围需要根据我可以从表中获得的最小和最大年龄动态生成。

【问题讨论】:

你需要通过什么方式动态生成?您必须指定更多内容。例如,每 5 天获取最小值并更改组? 例如,如果最大年龄是 100,那么我需要从 0 到 100 的 5 天范围。 【参考方案1】:
with cte_ages as (
    select
        extract(day from (modify_date - insert_date))::int as age
    from document
), cte_groups as (
    select
        case when g.age = 1 then 0 else g.age end as gr_start,
        g.age + 4 as gr_end
    from generate_series(1, (select max(age) from cte_ages), 5) as g(age)
)
select
    g.gr_start::text || '-' || g.gr_end::text,
    count(a.age)
from cte_groups as g
    left outer join cte_ages as a on a.age between g.gr_start and g.gr_end
group by g.gr_start, g.gr_end
order by g.gr_start

sql fiddle demo

【讨论】:

非常感谢,第一次尝试,第一滴血:D【参考方案2】:

对不起,我不知道 postgres,但如果你可以将它转换为 postgres,它会起作用:

SELECT count(*)
FROM document
WHERE (TO_DAYS(modify_date) - TO_DAYS(insert_date)) < 11 
      AND (TO_DAYS(modify_date) - TO_DAYS(insert_date)) > 5

此查询计算 6 到 10 天之间修改的文档数。但是您必须运行并修改查询以修改天数范围。

【讨论】:

Postgres 中没有to_days() 函数 这就是为什么我说:“你可以把它转换成 postgres” :)【参考方案3】:

最简单的方法(不是最好的!)是通过联合:

select '0-5' as age, count(*) as count
from document where insert_date < [6 days])
union
select '6-10' as age, count(*) as count
from document where between insert_date [6 days] and [11 days])

【讨论】:

问题是,它不是动态范围。我需要这个请求来生成这些范围,具体取决于我可以从表中获得的最小和最大年龄。

以上是关于选择行数,按 PostgreSQL 中时间间隔的动态范围排序的主要内容,如果未能解决你的问题,请参考以下文章

数组中时间戳之间的平均间隔

R中时间序列数据的滑动时间间隔

/var/lib/postgresql/data 尽管有明确的插入和更新行,但 docker 中时间刻度的盲挂载文件夹数据不会更新

SQL开发实战技巧系列(十六):数据仓库中时间类型操作(初级)日月年时分秒之差及时间间隔计算

有时间格式为200512和201201,在EXCEL中如何计算这两个时间的月间隔。

excel横坐标中时间刻度如何设置成整点?