仅针对多种类型中的一种折叠和求和组
Fold and sum groups only for one of many types
一开始我有一个table的付款,相关数据是这样的
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
我想要的是将类型为 'Payment' 的所有行折叠成总和、开始和结束期间的形式,所有其他必须相同,所以结果看起来像这样
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、group by、lag 和其他,找不到正确的方法
UPD:link 到 sql fiddle 工作结果 http://sqlfiddle.com/#!15/3cfea/1/0
这有点棘手。您可以使用行号差异技巧来获取付款组。然后您可以使用 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);
一开始我有一个table的付款,相关数据是这样的
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
我想要的是将类型为 'Payment' 的所有行折叠成总和、开始和结束期间的形式,所有其他必须相同,所以结果看起来像这样
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、group by、lag 和其他,找不到正确的方法
UPD:link 到 sql fiddle 工作结果 http://sqlfiddle.com/#!15/3cfea/1/0
这有点棘手。您可以使用行号差异技巧来获取付款组。然后您可以使用 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);