SQL/ Bigquery 排名或 row_number 在列更改值时重置
SQL/ Bigquery rank or row_number that resets when column changes value
我有一个 sql (bigquery) table 如下所示。
| Name | DaysToGo |Task |ID |
|:-----:|:--------:|:------:|:--:|
| Joe | 50 | A | 1 |
| Joe | 49 | A | 2 |
| Joe | 48 | B | 1 |
| Joe | 47 | B | 2 |
| Joe | 46 | B | 3 |
| Joe | 45 | A | 1 |
| Joe | 47 | A | 2 |
| Joe | 46 | A | 3 |
| Tim | 50 | B | 1 |
| Tim | 49 | B | 2 |
| Tim | 48 | B | 3 |
| Tim | 47 | C | 1 |
| Tim | 46 | B | 1 |
| Tim | 45 | B | 2 |
| Tim | 47 | C | 1 |
| Tim | 46 | C | 2 |
我希望根据 "Task" 列中的更改创建 "ID" 列,并按名称进行分区。本质上,每次 "Task" 更改并从 1 重新启动 ID 计数器时,"ID" 应重置为 1。
我尝试了排名、行号甚至滞后函数,但似乎无法找到合适的解决方案。
有什么想法吗?
这是一种间隙和孤岛问题。在这种情况下,我建议行号的差异:
select t.*,
row_number() over (partition by name, task, seqnum - seqnum_t
order by daystogo desc
) as id
from (select t.*,
row_number() over (partition by name order by daystogo) as seqnum,
row_number() over (partition by name, task order by daystogo) as seqnum_t
from t
) t;
为什么这行得通有点难以解释。如果您查看子查询的结果,您将看到两个 row_number()
值之间的差异如何识别每个人的相邻任务。外部查询使用此差异为最终结果分配新的 row_number()
。
我有一个 sql (bigquery) table 如下所示。
| Name | DaysToGo |Task |ID |
|:-----:|:--------:|:------:|:--:|
| Joe | 50 | A | 1 |
| Joe | 49 | A | 2 |
| Joe | 48 | B | 1 |
| Joe | 47 | B | 2 |
| Joe | 46 | B | 3 |
| Joe | 45 | A | 1 |
| Joe | 47 | A | 2 |
| Joe | 46 | A | 3 |
| Tim | 50 | B | 1 |
| Tim | 49 | B | 2 |
| Tim | 48 | B | 3 |
| Tim | 47 | C | 1 |
| Tim | 46 | B | 1 |
| Tim | 45 | B | 2 |
| Tim | 47 | C | 1 |
| Tim | 46 | C | 2 |
我希望根据 "Task" 列中的更改创建 "ID" 列,并按名称进行分区。本质上,每次 "Task" 更改并从 1 重新启动 ID 计数器时,"ID" 应重置为 1。
我尝试了排名、行号甚至滞后函数,但似乎无法找到合适的解决方案。 有什么想法吗?
这是一种间隙和孤岛问题。在这种情况下,我建议行号的差异:
select t.*,
row_number() over (partition by name, task, seqnum - seqnum_t
order by daystogo desc
) as id
from (select t.*,
row_number() over (partition by name order by daystogo) as seqnum,
row_number() over (partition by name, task order by daystogo) as seqnum_t
from t
) t;
为什么这行得通有点难以解释。如果您查看子查询的结果,您将看到两个 row_number()
值之间的差异如何识别每个人的相邻任务。外部查询使用此差异为最终结果分配新的 row_number()
。