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

Oracle两层嵌套SQL查询优化:取批次最后完成任务及PO完成率

问题核心原因

将PO金额统计的窗口求和逻辑下沉到最内层查询后,后续筛选last_task_finish_seq=1的操作会过滤掉同批次下其他PO关联行,导致金额统计仅基于筛选后的单条任务行,若该行不符合po_status=101或po_type=100的条件,就会出现求和结果为0的错误。

PostgreSQL 最优实现(无嵌套单层查询)
SELECT DISTINCT ON (custom_lot_no)
    custom_lot_no,
    -- 最后修改的已完成任务相关字段
    task_id,
    task_name,
    task_finish_time,
    task_modify_time,
    -- 全批次已完成PO总额
    SUM(CASE WHEN po_status = 101 THEN po_total_amount ELSE 0 END) OVER (PARTITION BY custom_lot_no) AS finished_po_amount,
    -- 全批次总承诺PO总额
    SUM(CASE WHEN po_type = 100 THEN po_total_amount ELSE 0 END) OVER (PARTITION BY custom_lot_no) AS committed_po_amount,
    -- 完成率,添加除0防护
    CASE 
        WHEN SUM(CASE WHEN po_type = 100 THEN po_total_amount ELSE 0 END) OVER (PARTITION BY custom_lot_no) = 0 THEN 0 
        ELSE ROUND(
            SUM(CASE WHEN po_status = 101 THEN po_total_amount ELSE 0 END) OVER (PARTITION BY custom_lot_no) 
            / SUM(CASE WHEN po_type = 100 THEN po_total_amount ELSE 0 END) OVER (PARTITION BY custom_lot_no)
            ,4
        )
    END AS po_completion_rate
FROM project_complete_data
-- 过滤已完成的任务,可替换为实际的任务完成判定条件
WHERE task_status = '已完成'
-- 同批次内按任务修改时间倒序,DISTINCT ON会自动保留每个分组的第一条
ORDER BY custom_lot_no, task_modify_time DESC;
MySQL/Oracle 兼容实现(仅一层嵌套)
SELECT 
    custom_lot_no,
    task_id,
    task_name,
    task_finish_time,
    finished_po_amount,
    committed_po_amount,
    po_completion_rate
FROM (
    SELECT 
        custom_lot_no,
        task_id,
        task_name,
        task_finish_time,
        SUM(CASE WHEN po_status = 101 THEN po_total_amount ELSE 0 END) OVER (PARTITION BY custom_lot_no) AS finished_po_amount,
        SUM(CASE WHEN po_type = 100 THEN po_total_amount ELSE 0 END) OVER (PARTITION BY custom_lot_no) AS committed_po_amount,
        CASE 
            WHEN SUM(CASE WHEN po_type = 100 THEN po_total_amount ELSE 0 END) OVER (PARTITION BY custom_lot_no) = 0 THEN 0 
            ELSE ROUND(
                SUM(CASE WHEN po_status = 101 THEN po_total_amount ELSE 0 END) OVER (PARTITION BY custom_lot_no) 
                / SUM(CASE WHEN po_type = 100 THEN po_total_amount ELSE 0 END) OVER (PARTITION BY custom_lot_no)
                ,4
            )
        END AS po_completion_rate,
        -- 同批次已完成任务按修改时间倒序排序
        ROW_NUMBER() OVER (PARTITION BY custom_lot_no ORDER BY task_modify_time DESC) AS rn
    FROM project_complete_data
    WHERE task_status = '已完成'
) t
WHERE rn = 1;
逻辑说明
  • 所有窗口计算在同一层级完成,数据源为全量已完成任务关联PO行,保证PO统计覆盖同批次所有符合要求的行
  • 两个窗口计算逻辑互相独立:按批次分区统计全批次PO金额汇总,同时按批次分区给已完成任务按修改时间倒序排序
  • 最后仅过滤排序首位的行,此时PO统计值已计算完成,不会受过滤操作影响
  • 相比原两层嵌套写法,仅需一次原表扫描,执行效率更高,结构更简洁

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 13:54:07