sql - 如何使用 Lag Lead 或窗口函数根据列值合并行开始日期结束日期?

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

我有一个包含 4 列的表:ID、STARTDATE、ENDDATE 和 BADGE。我想根据 ID 和 BADGE 值合并行,但要确保只有连续的行才会被合并。

例如,如果输入是:

enter image description here

输出将是:

enter image description here

我尝试过滞后领先、无界、有界前导,但无法实现输出:

SELECT ID, 
       STARTDATE, 
       MAX(ENDDATE), 
       NAME 
FROM (SELECT USERID, 
             IFF(LAG(NAME) over(Partition by USERID Order by STARTDATE) = NAME, 
                 LAG(STARTDATE) over(Partition by USERID Order by STARTDATE), 
                 STARTDATE) AS STARTDATE, 
             ENDDATE, 
             NAME 
      from myTable ) 
GROUP BY USERID, 
         STARTDATE, 
         NAME

我们必须确保仅合并具有相同 ID 和徽章的连续行。

我们将不胜感激,谢谢。

最佳答案

您可以将问题分为两个步骤:

  • 创建正确的分区
  • 使用直接聚合函数(MINMAX)对分区进行聚合

当没有连续的日期匹配时,您可以使用 bool 字段 1 来完成第一步(row1.ENDDATE = row2.STARTDATE + 1 天)。该值将指示何时应创建新分区。因此,如果您计算运行总和,您应该拥有正确编号的分区。

WITH cte AS (
    SELECT *,
           IFF(LAG(ENDDATE) OVER(PARTITION BY ID, Badge ORDER BY STARTDATE) + INTERVAL 1 DAY = STARTDATE , 0, 1) AS boolval
    FROM tab 
)
SELECT *
       SUM(COALESCE(boolval, 0)) OVER(ORDER BY ID DESC, STARTDATE) AS rn
FROM cte

然后第二步可以总结为使用 MIN 直接聚合“STARTDATE”和“ENDDATE” MAX 函数分别根据您的排名值进行分组。为了语法正确性,您还需要在 GROUP BY 子句中添加“ID”和“Badge”,即使它们的作用范围是已被计算的排名值捕获。

WITH cte AS (
    SELECT *,
           IFF(LAG(ENDDATE) OVER(PARTITION BY ID, Badge ORDER BY STARTDATE) + INTERVAL 1 DAY = STARTDATE , 0, 1) AS boolval
    FROM tab 
), cte2 AS (
    SELECT *,
           SUM(COALESCE(boolval, 0)) OVER(ORDER BY ID DESC, STARTDATE) AS rn
    FROM cte
)
SELECT ID,
       MIN(STARTDATE) AS STARTDATE,
       MAX(ENDDATE) AS ENDDATE,
       Badge
FROM cte2
GROUP BY ID,
         Badge,
         rn

关于sql - 如何使用 Lag Lead 或窗口函数根据列值合并行开始日期结束日期?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72754066/

相关文章:

SQL:PARTITION BY 和 GROUP BY 之间的区别

sql - 前几行数组的累积数组?

sql - Postgresql 8.4 - 限制窗口函数范围

mysql - 插入到如果不存在则不插入

mysql - 如何获取在 MYSQL 8 中列值更改之前首次出现的选择行

python - 雪花 Pandas pd_writer用NULL写入表

sql - 获取负数最大的行,如果没有负数则获取最小数的行

sql - Stack Overflow 查询以选择具有 3 个或更多答案的问题

mysql - 如何递归选择MySQL表中的所有 parent ?

javascript - 处理 Snowflake 中调用多个存储过程的异常