如何根据 Impala SQL 中的条件查找最长的子序列

How to find longest subsequence based on conditions in Impala SQL

我在 Impala 上有一个 SQL table,其中包含 IDdt(没有跳过的月)和 status 每个人的 ID。我想检查每个 ID 在每个状态下的时间(我的预期答案显示在 expected 列)

我试图通过使用

解决value列上的这个问题
count(status) over (partition by ID, status order by dt)

但当 status 更改时它不会重置 value

+------+------------+--------+-------+----------+
|  ID  |     dt     | status | value | expected |
+------+------------+--------+-------+----------+
| 0001 | 01/01/2020 |      0 |     1 |        1 |
| 0001 | 01/02/2020 |      0 |     2 |        2 |
| 0001 | 01/03/2020 |      1 |     1 |        1 |
| 0001 | 01/04/2020 |      1 |     2 |        2 |
| 0001 | 01/05/2020 |      1 |     3 |        3 |
| 0001 | 01/06/2020 |      0 |     3 |        1 |
| 0001 | 01/07/2020 |      1 |     4 |        1 |
| 0001 | 01/08/2020 |      1 |     5 |        2 |
+------+------------+--------+-------+----------+

status 改变时,是否有重置计数器的方法?

IDstatus划分时,status字段中的值01形成两组。因此,月份 1, 2, 6 进入 第一个 组,状态为 0 ,月份 3, 4, 5, 7, 8 进入 第二个 [=35] =] 状态为 1 的组。然后,计数函数分别计算这些组中的状态数。因此 first 组的计数从 13second 组的计数从 15。到目前为止,此查询并未考虑状态的变化,而只是根据不同的状态值简单地划分记录集。

一种方法是将记录分成不同的块,其中每个状态更改都会启动一个新块。下面的查询遵循这种方法并给出了预期的结果:

SELECT ID,dt,status,
    COUNT(status) OVER(PARTITION BY ID,block_number ORDER BY dt) as value 
FROM (
    SELECT ID,dt,status,
        SUM(change_in_status) OVER(PARTITION BY ID ORDER BY dt) as block_number
    FROM(
        SELECT ID,dt,status,
            CASE WHEN 
                    status<>LAG(status) OVER(PARTITION BY ID ORDER BY dt)
                    OR LAG(status) OVER(PARTITION BY ID ORDER BY dt) IS NULL 
                THEN 1 
                ELSE 0 
            END as change_in_status 
        FROM statuses
    ) derive_status_changes
) derive_blocks;

这是数据库 Fiddle 中的一个 working example