sql - 从 x 年前开始计算运行总和

标签 sql postgresql select sum

我有一个包含实体名称、年份和事件编号的表格 吼叫。在某些年份没有任何事件。

name | year | act_num
-----+------+---------
aa   | 2000 |       2
aa   | 2001 |       6
aa   | 2002 |       9
aa   | 2003 |      15
aa   | 2005 |      17
b    | 2000 |       3
b    | 2002 |       4
b    | 2003 |       9
b    | 2005 |      12
b    | 2006 |       2

在postgresql上创建;

CREATE TABLE entity_year_activity (
name character varying(10),
year integer,
act_num integer
);

INSERT INTO entity_year_activity
VALUES
    ('aa', 2000, 2),
    ('aa', 2001, 6),
    ('aa', 2002, 9),
    ('aa', 2003, 15),
    ('aa', 2005, 17),
    ('b', 2000, 3),
    ('b', 2002, 4),
    ('b', 2003, 9),
    ('b', 2005, 12),
    ('b', 2006, 2);

我想知道过去x年的总数 每个实体每年的事件数量如下。

以 x = 三年为例。

name | year | act_num | total_3_years
-----+------+---------+---------------
aa   | 2000 |       2 |      2
aa   | 2001 |       6 |      8
aa   | 2002 |       9 |     17
aa   | 2003 |      15 |     30
aa   | 2004 |       0 |     24
aa   | 2005 |      17 |     32
b    | 2000 |       3 |      3
b    | 2001 |       0 |      3
b    | 2002 |       4 |      7
b    | 2003 |       9 |     13
b    | 2005 |      12 |     21
b    | 2006 |       2 |     14

最佳答案

这是一种方法,它使用 sum 聚合作为具有基于范围的窗口框架的窗口函数的能力 - 请参阅 SUM(...) OVER (PARTITION BY name ORDER按年份 ROWS 2 PRECEDING)window framing .

WITH name_years(gen_name, gen_year) AS (
  SELECT gen_name, s
  FROM generate_series(
    (SELECT min(year) FROM entity_year_activity),
    (SELECT max(year) FROM entity_year_activity)
  ) s CROSS JOIN (SELECT DISTINCT name FROM entity_year_activity) n(gen_name)
),
windowed_history(name, year,act_num,last3_actnum) AS (
  SELECT
    gen_name, gen_year, coalesce( act_num, 0),
    SUM(coalesce(act_num,0)) OVER (PARTITION BY gen_name ORDER BY gen_year ROWS 2 PRECEDING)
  FROM name_years 
  LEFT OUTER JOIN entity_year_activity ON (gen_name = name AND gen_year = year)
)
SELECT name, year, act_num, sum(last3_actnum) as total_3_years
FROM windowed_history
GROUP BY name, year, act_num
HAVING sum(last3_actnum) <> 0
ORDER BY name, year;

参见 SQLFiddle .

需要为本身没有条目的年份生成条目使此查询变得复杂。我生成了一个包含所有 (name, year) 对的表,然后 left outer join entity_year_activity 在执行窗口总和之前对其进行处理,因此表示所有名称集的所有年份。这就是为什么它如此复杂。然后我过滤聚合结果以排除总和为零的条目。

关于sql - 从 x 年前开始计算运行总和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13069214/

相关文章:

javascript - 使用 jQuery,当从下拉菜单中选择时,我需要从更改事件中捕获正确的变量

sql - SQL Server 2008 上的批量删除(有类似批量复制 (bcp) 之类的用于删除数据的功能吗?)

mysql - 如何从mysql过程中的表中获取新列?

mysql - 在具有预定义值的两个日期属性之间进行选择

mongodb - Postgres 和 Mongodb 的双向数据库同步

postgresql - 使用 ALTER 语句更改字符不同长度?

c# - Npgsql + Dapper ExecuteReader

sql - 添加字段以优化 MySQL 查询

mysql - 如何在唯一选择中获取条目数和列名?

postgresql - 选择后postgres更新