【问题标题】:How to get first row of each status?如何获得每个状态的第一行?
【发布时间】:2021-08-23 19:33:25
【问题描述】:

我想获取每个 id 的每个状态的第一行。

每个状态可以有多行。所以我想根据之前的状态来获取每个状态的第一次出现。

例如info_required 首先出现在第 2 行,然后在第 4 行变为另一个状态 pending,然后在第 6 行再次变为 info_required。 同样,状态 pending 首先在第 4 行,然后在第 8 行,因为在第 4 行之后状态发生了变化,它需要在结果集中。

因此我想在下面获取第 1、2、4、6 和 8 行。

WITH t1 AS (
SELECT 1 AS row, 'A' AS id, 'created' AS status, '2021-05-18 18:30:00'::timestamp AS created_at UNION ALL
SELECT 2 AS row, 'A' AS id, 'info_required' AS status, '2021-05-19 11:30:00'::timestamp AS created_at UNION ALL
SELECT 3 AS row, 'A' AS id, 'info_required' AS status, '2021-05-19 12:00:00'::timestamp AS created_at UNION ALL
SELECT 4 AS row, 'A' AS id, 'pending' AS status, '2021-05-19 12:30:00'::timestamp AS created_at UNION ALL
SELECT 5 AS row, 'A' AS id, 'pending' AS status, '2021-05-20 13:30:00'::timestamp AS created_at UNION ALL
SELECT 6 AS row, 'A' AS id, 'info_required' AS status, '2021-05-20 14:30:00'::timestamp AS created_at UNION ALL
SELECT 7 AS row, 'A' AS id, 'info_required' AS status, '2021-05-20 15:30:00'::timestamp AS created_at UNION ALL
SELECT 8 AS row, 'A' AS id, 'pending' AS status, '2021-05-20 16:30:00'::timestamp AS created_at
    )
SELECT *
FROM t1

【问题讨论】:

    标签: sql snowflake-cloud-data-platform window-functions


    【解决方案1】:

    使用CONDITIONAL_CHANGE_EVENT

    WITH cte AS (
      SELECT *, CONDITIONAL_CHANGE_EVENT(status) over (partition by id 
                                                       order by created_at) AS cce
      FROM t1
    )
    SELECT *
    FROM cte
    QUALIFY ROW_NUMBER() OVER(PARTITION BY id, cce ORDER BY created_at) = 1;
    


    数据准备:

    CREATE TABLE t1 AS 
    WITH t1 AS (
    SELECT 1 AS row_, 'A' AS id, 'created' AS status, '2021-05-18 18:30:00'::timestamp AS created_at UNION ALL
    SELECT 2 AS row_, 'A' AS id, 'info_required' AS status, '2021-05-19 11:30:00'::timestamp AS created_at UNION ALL
    SELECT 3 AS row_, 'A' AS id, 'info_required' AS status, '2021-05-19 12:00:00'::timestamp AS created_at UNION ALL
    SELECT 4 AS row_, 'A' AS id, 'pending' AS status, '2021-05-19 12:30:00'::timestamp AS created_at UNION ALL
    SELECT 5 AS row_, 'A' AS id, 'pending' AS status, '2021-05-20 13:30:00'::timestamp AS created_at UNION ALL
    SELECT 6 AS row_, 'A' AS id, 'info_required' AS status, '2021-05-20 14:30:00'::timestamp AS created_at UNION ALL
    SELECT 7 AS row_, 'A' AS id, 'info_required' AS status, '2021-05-20 15:30:00'::timestamp AS created_at UNION ALL
    SELECT 8 AS row_, 'A' AS id, 'pending' AS status, '2021-05-20 16:30:00'::timestamp AS created_at
    )
    SELECT *
    FROM t1;
    

    Cte部分:

    SELECT *, CONDITIONAL_CHANGE_EVENT(status) over (partition by id 
                                                  order by created_at) AS cce
    FROM t1;
    

    【讨论】:

      【解决方案2】:

      您可以使用lag()qualify()

      select t.*
      from t
      qualify lag(status) over (partition by id order by created_at) is distinct from status;
      

      【讨论】:

        猜你喜欢
        • 2022-11-24
        • 1970-01-01
        • 2017-01-20
        • 1970-01-01
        • 2016-02-09
        • 2019-08-31
        • 2019-02-27
        • 2021-01-24
        • 1970-01-01
        相关资源
        最近更新 更多