You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

解决GROUP BY合并非连续重复SUPERVISOR_ID的最优方案

问题:按连续时间分组同一主管的记录

我遇到的问题较难描述,以下通过数据说明:

原始数据

EMPLOYEE_IDEMPLOYEE_SUPERVISOR_IDEFFECTIVE_START_DATEEFFECTIVE_END_DATE
306656104630/04/202130/09/2021
30665800909830/09/202131/12/2021
30665800909831/12/202131/07/2022
306657328031/07/202231/08/2022
306657328031/08/202230/09/2022
306657328030/09/202230/09/2023
306657328003/10/202331/10/2023
306657328031/10/202301/12/2023
306657962101/12/202304/12/2023
306657962101/12/202304/12/2023
306657328004/12/202315/01/2024
306657328015/01/202415/03/2024
306657328015/03/202414/05/2024
306657328014/05/202415/05/2024
306657328015/05/202417/05/2024

我尝试使用以下SQL查询来获取所需结果:

SELECT
    EMPLOYEE_ID,
    SUPERVISOR_ID,
    MIN(EFFECTIVE_START) AS "EFFECTIVE_START",
    MAX(EFFECTIVE_END) AS "EFFECTIVE_END"
FROM
    EMP_TABLE
GROUP BY
    1, 2
ORDER BY
    EFFECTIVE_START ASC

当前错误结果

问题在于SUPERVISOR_ID为73280的记录被错误合并,出现重复分组结果:

EMPLOYEE_IDSUPERVISOR_IDEFFECTIVE_STARTEFFECTIVE_END
306656104630/04/202130/09/2021
30665800909830/09/202131/07/2022
306657328031/07/202201/12/2023
306657328031/07/202217/05/2024
306657962101/12/202304/12/2023

期望结果

按时间连续的同一主管进行分组,正确结果如下:

EMPLOYEE_IDSUPERVISOR_IDEFFECTIVE_STARTEFFECTIVE_END
306656104630/04/202130/09/2021
30665800909830/09/202131/07/2022
306657328031/07/202201/12/2023
306657962101/12/202304/12/2023
306657328004/12/202317/05/2024

解决方案

这属于典型的连续相同分组(岛屿问题),需要用窗口函数识别主管变化的节点,再对连续的相同主管分组处理:

WITH ranked_data AS (
    SELECT
        EMPLOYEE_ID,
        EMPLOYEE_SUPERVISOR_ID AS SUPERVISOR_ID,
        EFFECTIVE_START_DATE AS EFFECTIVE_START,
        EFFECTIVE_END_DATE AS EFFECTIVE_END,
        -- 标记主管变化的行,当当前主管与上一行不同时,生成新分组ID
        SUM(CASE WHEN LAG(EMPLOYEE_SUPERVISOR_ID) OVER (PARTITION BY EMPLOYEE_ID ORDER BY EFFECTIVE_START_DATE) = EMPLOYEE_SUPERVISOR_ID THEN 0 ELSE 1 END) 
        OVER (PARTITION BY EMPLOYEE_ID ORDER BY EFFECTIVE_START_DATE) AS group_id
    FROM EMP_TABLE
)
SELECT
    EMPLOYEE_ID,
    SUPERVISOR_ID,
    MIN(EFFECTIVE_START) AS EFFECTIVE_START,
    MAX(EFFECTIVE_END) AS EFFECTIVE_END
FROM ranked_data
GROUP BY EMPLOYEE_ID, SUPERVISOR_ID, group_id
ORDER BY EFFECTIVE_START;

逻辑说明:

  1. 用LAG函数获取当前行的上一行主管ID,判断是否与当前主管相同;
  2. 用SUM累加变化标记,生成唯一的分组ID,同一连续主管的记录会被分到同一个group_id;
  3. 最后按EMPLOYEE_ID、SUPERVISOR_ID和group_id分组,取每组的最小开始时间和最大结束时间。

内容的提问来源于stack exchange,提问作者Sid

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 12:49:51