折叠和求和组仅适用于多种类型中的一种

时间:2016-09-05 15:30:16

标签: sql postgresql postgresql-9.5

首先我有一张付款表,相关数据看起来像这样

id     | price  | type     | ts
------ | -------|----------|---------------------------
1      | 50     | Payment  | 2016-06-24 16:01:00.000000
2      | 15     | Payment  | 2016-06-24 16:02:00.000000
3      | 5      | Refund   | 2016-06-24 16:03:00.000000
4      | 10     | Payment  | 2016-06-24 16:04:00.000000
5      | 20     | Payment  | 2016-06-24 16:05:00.000000
6      | 40     | Withdraw | 2016-06-24 16:06:00.000000
7      | 30     | Withdraw | 2016-06-24 16:07:00.000000
8      | 15     | Payment  | 2016-06-24 16:08:00.000000
9      | 25     | Payment  | 2016-06-24 16:09:00.000000

我想要的是折叠所有行类型='付款'为了形式的总和,开始和结束时期,所有其他必须是相同的,所以结果看起来像这样

id     | price  | type     | begin                     | end 
------ | -------|----------|---------------------------|---------------------------
null   | 65     | Payment  | 2016-06-24 16:01:00.000000| 2016-06-24 16:02:00.000000
3      | 5      | Refund   | 2016-06-24 16:03:00.000000|
null   | 30     | Payment  | 2016-06-24 16:04:00.000000| 2016-06-24 16:05:00.000000
6      | 40     | Withdraw | 2016-06-24 16:06:00.000000|
7      | 30     | Withdraw | 2016-06-24 16:07:00.000000|
null   | 40     | Payment  | 2016-06-24 16:08:00.000000| 2016-06-24 16:09:00.000000

如果它有一些标志,如行被分组,并支持限制最终结果

,它也会很有用

现在我停止尝试row_number,分组依据,滞后等,无法找到正确的方法

UPD :链接到sql小提示工作结果http://sqlfiddle.com/#!15/3cfea/1/0

1 个答案:

答案 0 :(得分:2)

这有点棘手。您可以使用行数技巧的差异来获取付款的组。然后,您可以使用case仅将其应用于付款本身(而不是其他值)。这看起来像:

select (case when type <> 'payment' then id) as id,
       sum(price) as price,
       min(type) as type,
       min(ts) as begin,
       max(case when type = 'payment' then ts end) as end
from (select t.*,
             (row_number() over (order by id) -
              row_number() over (partition by type order by id)
             ) as grp
      from t
     ) t
group by (case when type = 'payment' then grp end),
         (case when type <> 'payment' then id end);