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

如何将同表JOIN查询转换为GROUP BY查询?附场景需求

解决方案:纵向展示匹配记录的两种方案

针对你的需求——找出punches_history表中除TIMED字段差值小于2秒外,ClockNumber、PartNumber、Quantity、YYMMDD完全相同的记录,并纵向展示匹配的两条记录,以下是两种可行方案:

方案一:使用窗口函数(LEAD)实现纵向输出

利用窗口函数直接获取同组内的下一条记录,筛选符合条件的记录对后,通过UNION ALL将两条记录纵向拼接,避免横向拼接的繁琐查看。

WITH ranked_records AS (
    SELECT 
        *,
        -- 获取同组内下一条记录的TIMED值
        LEAD(TIMED) OVER (
            PARTITION BY ClockNumber, PartNumber, Quantity, YYMMDD 
            ORDER BY id
        ) AS next_timed,
        -- 获取同组内下一条记录的ID
        LEAD(id) OVER (
            PARTITION BY ClockNumber, PartNumber, Quantity, YYMMDD 
            ORDER BY id
        ) AS next_id,
        -- 获取同组内下一条完整记录
        LEAD(*) OVER (
            PARTITION BY ClockNumber, PartNumber, Quantity, YYMMDD 
            ORDER BY id
        ) AS next_record
    FROM punches_history
    WHERE ClockNumber != '10' AND CardColor = 'BLU'
)
-- 先输出当前符合条件的记录
SELECT * EXCEPT(next_timed, next_id, next_record)
FROM ranked_records
WHERE ABS(TIMED - next_timed) < 2 AND next_id = id + 1
UNION ALL
-- 再输出对应的匹配记录
SELECT next_record.*
FROM ranked_records
WHERE ABS(TIMED - next_timed) < 2 AND next_id = id + 1
ORDER BY YYMMDD DESC, ClockNumber DESC, id;

说明

  • PARTITION BY按指定的相同字段分组,确保只在同组内查找匹配记录
  • ORDER BY id保证按ID顺序获取下一条记录,避免重复匹配(如20和21、21和20)
  • UNION ALL将两条匹配记录纵向排列,方便查看

方案二:GROUP BY分组筛选后关联原表

先通过GROUP BY找出存在符合条件记录对的分组,再关联回原表取出具体记录,实现纵向展示。

WITH valid_groups AS (
    SELECT 
        ClockNumber, PartNumber, Quantity, YYMMDD,
        MIN(id) AS min_id,
        MAX(id) AS max_id,
        MAX(TIMED) AS max_timed,
        MIN(TIMED) AS min_timed
    FROM punches_history
    WHERE ClockNumber != '10' AND CardColor = 'BLU'
    GROUP BY ClockNumber, PartNumber, Quantity, YYMMDD
    -- 筛选出只有两条连续ID且时间差小于2秒的组
    HAVING MAX(id) = MIN(id) + 1 
       AND ABS(max_timed - min_timed) < 2
)
SELECT ph.*
FROM punches_history ph
JOIN valid_groups vg 
    ON ph.ClockNumber = vg.ClockNumber
    AND ph.PartNumber = vg.PartNumber
    AND ph.Quantity = vg.Quantity
    AND ph.YYMMDD = vg.YYMMDD
    AND ph.id IN (vg.min_id, vg.max_id)
ORDER BY ph.YYMMDD DESC, ph.ClockNumber DESC, ph.id;

说明

  • GROUP BY分组后,通过HAVING判断组内仅存在两条连续ID的记录,且时间差符合要求
  • 关联原表后直接取出这两条记录,自然纵向排列,无需横向拼接

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 05:27:19