在此表上构建(不使用SQL关键字“ date”作为列名。):
CREATE TABLE tbl( pid int, the_date date, PRIMARY KEY (pid, the_date));
询问:
SELECt pid, the_date , row_number() OVER (PARTITION BY pid, grp ORDER BY the_date) AS in_streakFROM ( SELECt * , the_date - '2000-01-01'::date - row_number() OVER (PARTITION BY pid ORDER BY the_date) AS grp FROM tbl) subORDER BY pid, the_date;
date从另一个减去a
date得到一个
integer。由于您一直在寻找连续的日子,因此下一行将增加 一
。如果
row_number()从中减去,则整个条纹最终将归入同一组(
grp)
pid。然后,很容易按组分配数字。
grp用两个减法计算得出,这应该是最快的。同样快速的替代方法可能是:
the_date - row_number() OVER (PARTITION BY pid ORDER BY the_date) * interval '1d' AS grp
一乘一减。字符串连接和转换更昂贵。用进行测试
EXPLAIN ANALYZE。
不要忘记
pid在 两个 步骤中 都 进行额外的分区,否则您会无意间混淆了应该分开的组。
使用子查询,因为它通常比CTE快。这里没有什么是普通子查询无法完成的。
既然您提到了它:在这里
dense_rank()显然 没有
必要。基本
row_number()完成工作。



