【发布时间】:2020-11-22 15:56:47
【问题描述】:
如何按 SQL 中每个序列的第一个值对序列数据集进行分组?
例如,我有以下数据集
id name key metric
1 alice a 0 <- key = 'a', start of a sequence
2 alice b 1
3 alice b 1
-----------------
4 alice a 1 <- key = 'a', start of a sequence
5 alice b 0
6 alice b 0
7 alice b 0
-----------------
8 bob a 1 <- key = 'a', start of a sequence
9 bob b 1
-----------------
10 bob a 0 <- key = 'a', start of a sequence
key = 'a' 的行开始一个新组。例如,我想对所有后续行的指标求和,直到达到另一个 key = 'a' 或另一个 name。
数据集按id排序。
最终的结果应该是这样的:
id name metric
1 alice 2
4 alice 1
8 bob 2
10 bob 0
这是 JavaScript 中的等效操作,但我希望能够通过 SQL 查询获得相同的结果。
data.reduce((acc, a) => {
if(a.key === 'a'){
// key = 'a' starts a new group
return [{id: a.id, name: a.name, metric: a.metric}].concat(acc)
} else {
// because the data is sorted,
// all the subsequent rows with key = 'b' belong to the latest group
const [head, ...tail] = acc
const head_updated = {...head, metric: head.metric + a.metric}
return [head_updated, ...tail]
}
}, [])
.reverse()
示例 SQL 数据集:
with dataset as (
select
1 as id
, 'alice' as name
, 'a' as key
, 0 as metric
union select
2 as id
, 'alice' as name
, 'b' as key
, 1 as metric
union select
3 as id
, 'alice' as name
, 'b' as key
, 1 as metric
union select
4 as id
, 'alice' as name
, 'a' as key
, 1 as metric
union select
5 as id
, 'alice' as name
, 'b' as key
, 0 as metric
union select
6 as id
, 'alice' as name
, 'b' as key
, 0 as metric
union select
7 as id
, 'alice' as name
, 'b' as key
, 0 as metric
union select
8 as id
, 'bob' as name
, 'a' as key
, 1 as metric
union select
9 as id
, 'bob' as name
, 'b' as key
, 1 as metric
union select
10 as id
, 'bob' as name
, 'a' as key
, 0 as metric
)
select * from dataset
order by name, id
【问题讨论】:
标签: sql postgresql amazon-redshift window-functions