我需要在查询中显示每行的连续赢/输,所以给定下表,查询应该返回“预期”列。我尝试了一些使用窗口函数的方法,但没有成功。
create table matches (player text, dt date, is_winner boolean, expected integer )
insert into matches values
('A', '2019-01-01', TRUE, 0),
('A', '2019-01-03', TRUE, 1),
('A', '2019-01-04', TRUE, 2),
('A', '2019-01-09', FALSE, 0),
('A', '2019-01-10', FALSE, -1),
('A', '2019-01-15', TRUE, 0);
player dt is_winner expected
A 2019-01-01 true 0
A 2019-01-03 true 1
A 2019-01-04 true 2
A 2019-01-09 false 0
A 2019-01-10 false -1
A 2019-01-15 true 0
逻辑是:
- 输后赢或赢后输时重置为 0。
- 获胜后增加,但如果是案例 1,则不会增加。
- 亏损后递减,但如果是第一种情况则不会。
欢迎任何有关如何解决此问题的见解。我最后的手段是每行都调用一个循环的函数。
我已经使用 CTE 分阶段完成了这项工作,以便您可以在查询进行时看到它是如何完成的。每个 CTE 在输出中添加一列以显示进度。
老实说,它几乎是用 CTE 名称自我记录的。
DB Fiddle Link(我添加了一个额外的行只是为了确保它在某个点工作)
基本上:
lags
CTE:用于LAG()
获取相对于当前行的上一个结果。group_changes
CTE:检测之前的连胜,无论输赢,是否已经结束groups_numbered
CTE:给每个连胜一个数字expected_in_groups
CTE:对组中的行进行编号select
:否定连败.