Postgres以行比较为条件汇总和

时间:2017-01-06 20:07:14

标签: postgresql window-functions

所以,我的数据看起来像这样

User_Object | filesize | created_date | deleted_date
row 1       | 40        | May 10       | Aug 20
row 2       | 10        | June 3       | Null
row 3       | 20        | Nov 8        | Null

我正在建立统计数据,以便根据基于时间的数据点记录用户数据使用情况。但是,我很难开发一个查询来为它之前的所有查询的每一行取总和,但仅限于该行创建时存在的行。在采取此步骤合并已删除的值之前,我有一个简单的天真查询,如下所示:

SELECT User_Object.id, User_Object.created, SUM(filesize) OVER (ORDER BY User_Object.created) AS sum_data_used
    FROM User_Object
    JOIN user ON User_Object.user_id = user.id
    WHERE user.id = $1

但是,我想以某种方式改变它,以便窗口函数有条件只获得在此用户对象之前创建的任何行的总和,此行在此用户对象之前也没有删除日期。

这种不正确的语法说明了我想要做的事情:

SELECT User_Object.id, User_Object.created, 
        SUM(CASE WHEN NOT window_function_row.deleted
            OR window_function_row.deleted > User_Object.created
            THEN filesize ELSE 0)
        OVER (ORDER BY User_Object.created) AS sum_data_used
    FROM User_Object
    JOIN user ON User_Object.user_id = user.id
    WHERE user.id = $1

当此函数对我拥有的数据运行时,它应输出类似

的内容
id      | created | sum_data_used|
1       | May 10  | 40
2       | June 3  | 50
3       | Nov 8   | 30

1 个答案:

答案 0 :(得分:1)

这些方面的某些内容可能适合您:

SELECT a.user_id
      ,MIN(a.created_date) AS created_date
      ,SUM(b.filesize) AS sum_data_used
  FROM user_object a
  JOIN user_object b ON (b.user_id <= a.user_id
                    AND COALESCE(b.deleted_date, a.created_date) >= a.created_date)
  GROUP BY a.user_id
  ORDER BY a.user_id

对于每一行,自联接,匹配id更低或相等,并且日期重叠。这将是昂贵的,因为每行需要查看整个表来计算文件大小结果。这里没有累积操作。但我不确定是否有办法。

示例表定义:

create table user_object(user_id int, filesize int, created_date date, deleted_date date);

数据:

1;40;2016-05-10;2016-08-29
2;10;2016-06-03;<NULL>
3;20;2016-11-08;<NULL>

结果:

1;2016-05-10;40
2;2016-06-03;50
3;2016-11-08;30