【问题标题】:SQL/ Bigquery rank or row_number that resets when column changes value列更改值时重置的 SQL/Bigquery rank 或 row_number
【发布时间】:2019-10-30 16:47:21
【问题描述】:

我有一个如下所示的 sql (bigquery) 表。

| 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  |

我希望根据“任务”列中的更改创建“ID”列,按名称分区。本质上,每次“任务”更改并从 1 重新启动 ID 计数器时,“ID”都应重置为 1。

我尝试了排名、行号甚至滞后函数,但似乎无法找到合适的解决方案。 有什么想法吗?

【问题讨论】:

    标签: sql row rank gaps-and-islands


    【解决方案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()

    【讨论】:

    猜你喜欢
    • 2016-01-19
    • 1970-01-01
    • 2018-04-12
    • 2020-03-07
    • 2022-12-08
    • 2019-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多