PostgreSQL:随时间变化的行数

Posted

技术标签:

【中文标题】PostgreSQL:随时间变化的行数【英文标题】:PostgreSQL: Row count over time 【发布时间】:2015-08-25 08:34:00 【问题描述】:

我有一个简单的 mysql sql 脚本,它输出特定表随时间变化的行数(基于表中的日期时间字段)

SELECT concat('M-', s.label)
     , s.cnt
     , @tot := @tot + s.cnt  AS running_subtotal
  FROM ( SELECT DATE_FORMAT(t.created,'%y-%m') AS `label`
              , COUNT(t.id) AS cnt
           FROM `templates` t
          GROUP BY `label`
          ORDER BY `label`
       ) s
 CROSS
  JOIN ( SELECT @tot := 0 ) i

现在我想将它迁移到 PostgreSQL,但不知道如何将变量迁移到基于 pg 的语法。

内部语句当然没问题:

SELECT TO_CHAR(t.created,'YYYY-MM') AS label
              , COUNT(t.id) AS cnt
           FROM templates t
          GROUP BY label
          ORDER BY label

这里有谁可以帮我解决可变部分的问题吗?

这是一个包含数据的简单表格:

create TABLE "templates" (
    "id" bigserial,
    "title" varchar(2048) default NULL::character varying,
    "created" timestamp,
    PRIMARY KEY ("id")
);

insert into templates(title, created) values('test', '2011-03-01');
insert into templates(title, created) values('test 2', '2011-03-02');
insert into templates(title, created) values('test 3', '2011-03-03');
insert into templates(title, created) values('test 4', '2011-03-04');
insert into templates(title, created) values('test 5', '2011-03-05');
insert into templates(title, created) values('test 6', '2011-04-01');
insert into templates(title, created) values('test 7', '2011-04-02');
insert into templates(title, created) values('test 8', '2011-04-03');
insert into templates(title, created) values('test 9', '2011-04-04');
insert into templates(title, created) values('test 10', '2011-04-05');
… // 300 more for 2011-05

此查询的示例输出(基于带有“created”列的记录)是:

M-11-03:5 5 M-11-04:5 10(5 + 5) M-11-05:300 310(5 + 5 + 300)

(这是Table statistics (aka row count) over time的衍生产品)

【问题讨论】:

postgresql.org/docs/9.3/static/tutorial-window.html 您可能需要一些窗口功能。但是,如果您需要帮助,请通过添加一些数据以及您真正期望的结果来更新您的问题。 谢谢@Houari!我添加了示例输出以便于识别目标。 @wingedpanther 完成! 无需将日期转换为字符。您可以选择和聚合date_trunc('mon', created) 【参考方案1】:

这行得通:

select month, hm, sum(hm) over(order by month)
from(
select to_char(created, 'M-YYYY-MM') as month, count(*) as hm
from templates
group by 1
) x
order by month

http://www.sqlfiddle.com/#!15/eb08a/14

【讨论】:

【参考方案2】:

对于日期格式,您可以使用M-YY-MM 作为格式字符串来获取例如:M-11-03。 通过使用聚合countwindow function

SELECT distinct TO_CHAR(created,'M-YY-MM'), 
       COUNT(id) OVER ( ORDER BY TO_CHAR(created,'YY-MM')) 
FROM templates 
ORDER BY 1

SQL FIDDLE

【讨论】:

@a_horse_with_no_name 查看此SQLFIDDLE 以查看没有distinct 的结果 非常好的代码!但我不确定如何将第二列(滚动总数)放入其中。我需要使用 sum(count_field) OVER ( ORDER BY date_field)) 进行连接吗?

以上是关于PostgreSQL:随时间变化的行数的主要内容,如果未能解决你的问题,请参考以下文章

使用 jOOQ UPserting 到 Postgres 表时返回更新的行数

如何获取 PostgreSQL 游标的行数?

如何加快计算 PostgreSQL 表中的行数?

postgresql函数-获取受更新查询影响的行数[重复]

postgres —— 窗口函数入门

选择 Count (distinct col) 查询以显示结果中的行数和列数 - postgresql