PostgreSQL窗口函数:按列分组而不排序(~Python itertools.groupby)

时间:2011-02-21 16:10:20

标签: sql postgresql

我需要在PostgreSQL中基于列进行分区而不进行排序&使结果独特;基本上我想要实现的是在PostgreSQL中重现Python中的itertools.groupby()行为。

鉴于该表包含两列:

1   C
2   C
3   C
4   C
5   C
6   C
7   C
8   C
9   C
10  S
11  E
12  E
13  E
14  E
15  E
16  C
17  C
18  C
19  C
20  E
21  E
22  E
23  E
24  E

我想用秒中的值对其进行分区(同时保留现有的顺序),以此结束:

1   C   1
2   C   1
3   C   1
4   C   1
5   C   1
6   C   1
7   C   1
8   C   1
9   C   1
10  S   2
11  E   3
12  E   3
13  E   3
14  E   3
15  E   3
16  C   4
17  C   4
18  C   4
19  C   4
20  E   5
21  E   5
22  E   5
23  E   5
24  E   5

我尝试使用窗口函数实现这一功能,使用ROW_NUMBER()LAG()的组合将当前行与上一行进行比较,以查看它是否已更改。在这种情况下的问题是我还需要一个变量,每次值变化时都会递增。

2 个答案:

答案 0 :(得分:2)

试试这个:

WITH T1 AS
(
    SELECT
        id,
        grp,
        LAG(grp) OVER (ORDER BY id) IS DISTINCT FROM grp AS changes
    FROM yourtable
)
SELECT id, grp, SUM(changes::int) OVER (ORDER BY id) FROM T1

答案 1 :(得分:1)

尽管可以提出完全基于窗口函数的解决方案,但结果集的这种状态处理似乎最适合迭代方法。这是一个问题之前有点类似的问题:PostgreSQL function to iterate through/act on many rows with state

基本上,仅窗口方法归结为在每个分区的开头生成一个“1”(或任何其他正整数)的整数列(所以col2<>LAG(col2)),然后使用另一个窗口聚合将这些组指标从结果集的开头加到当前行。它有效,它在复杂性和(我相信)性能方面都很难看。