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

MySQL 5按recurrence number及最新日期分组查询求助

问题:按分组获取每组最新日期的完整记录(MySQL 5)

原始查询及结果

以下查询返回符合条件的所有延迟记录:

SELECT 
    r.rec_num as Column_A
    ,c.amount as Column_B
    ,c.status as Column_C
    ,c.currency_code_to as Column_D
    ,c.due_date as Column_E
    ,c.id_recurrency as Column_F
FROM purchase c
JOIN recurrency r ON c.id_recurrency = r.id
JOIN item_product ip ON c.item_estoque = ip.id
JOIN signature a ON a.id = ip.signature
WHERE a.id = :id
    AND r.plano_signature IS NOT NULL
    AND r.rec_num IN (1,2,3,4)
    AND r.rec_num NOT IN (
        SELECT rn.recurrence
        FROM negotiate n
        JOIN negotiate_recurrence rn ON rn.negotiate = n.id
        JOIN purchase purchase ON purchase.id = n.purchase
        WHERE n.subscription = a.id
            AND rn.recurrence = r.rec_num
            AND purchase.status IN ('VALID','FILED')
        )
    AND r.rec_num NOT IN (
        SELECT r2.rec_num
        FROM purchase c2
        JOIN recurrency r2 ON c2.id_recurrency = r2.id
        JOIN item_product ip2 ON c2.item_estoque = ip2.id
        WHERE ip2.signature = a.id
            AND c2.status IN ('VALID','FILED')
        )
    AND c.id NOT IN (
        SELECT n1.purchase
        FROM negotiate n1
        WHERE n1.subscription = a.id
        )
    AND c.status = 'DELAYED'

查询结果:

Column AColumn BColumn CColumn DColumn EColumn F
21000DELAYEDBRL2023-10-04T19:48:17.000Z11102501
2250DELAYEDBRL2023-10-04T19:54:16.000Z11102502
2250DELAYEDBRL2023-10-09T23:30:20.000Z11102503
2250DELAYEDBRL2023-10-14T18:14:20.000Z12042504
3250DELAYEDBRL2023-11-04T12:51:33.000Z13842790

期望结果

需要按Column A(rec_num)分组,返回每组中Column E(due_date)最新的完整记录:

Column AColumn BColumn CColumn DColumn EColumn F
2250DELAYEDBRL2023-10-14T18:14:20.000Z12042504
3250DELAYEDBRL2023-11-04T12:51:33.000Z13842790

尝试的错误方法及结果

尝试用MAX(due_date)结合GROUP BY rec_num,但得到的结果不符合预期:

SELECT 
    r.rec_num as Column_A
    ,c.amount as Column_B
    ,c.status as Column_C
    ,c.currency_code_to as Column_D
    ,max(c.due_date) as Column_E
    ,c.id_recurrency as Column_F
FROM purchase c
JOIN recurrency r ON c.id_recurrency = r.id
JOIN item_product ip ON c.item_estoque = ip.id
JOIN signature a ON a.id = ip.signature
WHERE a.id = :id
    AND r.plano_signature IS NOT NULL
    AND r.rec_num IN (1,2,3,4)
    AND r.rec_num NOT IN (
        SELECT rn.recurrence
        FROM negotiate n
        JOIN negotiate_recurrence rn ON rn.negotiate = n.id
        JOIN purchase purchase ON purchase.id = n.purchase
        WHERE n.subscription = a.id
            AND rn.recurrence = r.rec_num
            AND purchase.status IN ('VALID','FILED')
        )
    AND r.rec_num NOT IN (
        SELECT r2.rec_num
        FROM purchase c2
        JOIN recurrency r2 ON c2.id_recurrency = r2.id
        JOIN item_product ip2 ON c2.item_estoque = ip2.id
        WHERE ip2.signature = a.id
            AND c2.status IN ('VALID','FILED')
        )
    AND c.id NOT IN (
        SELECT n1.purchase
        FROM negotiate n1
        WHERE n1.subscription = a.id
        )
GROUP BY r.rec_num

错误结果:

Column AColumn BColumn CColumn DColumn EColumn F
21000DELAYEDBRL2023-10-14T18:14:20.000Z11102501
3250DELAYEDBRL2023-11-04T12:51:33.000Z13842790

解决方案

问题原因

MySQL 5中,GROUP BY仅指定rec_num时,未被包含在分组中的列(如amount、id_recurrency)会随机选取分组内某一行的值,而非对应MAX(due_date)的那一行,导致结果错误。

正确查询(关联子查询方式)

由于MySQL 5不支持窗口函数(如ROW_NUMBER()),可以通过关联子查询找到每个rec_num对应的最大due_date,再筛选出该行的完整记录:

SELECT 
    r.rec_num as Column_A
    ,c.amount as Column_B
    ,c.status as Column_C
    ,c.currency_code_to as Column_D
    ,c.due_date as Column_E
    ,c.id_recurrency as Column_F
FROM purchase c
JOIN recurrency r ON c.id_recurrency = r.id
JOIN item_product ip ON c.item_estoque = ip.id
JOIN signature a ON a.id = ip.signature
WHERE a.id = :id
    AND r.plano_signature IS NOT NULL
    AND r.rec_num IN (1,2,3,4)
    AND r.rec_num NOT IN (
        SELECT rn.recurrence
        FROM negotiate n
        JOIN negotiate_recurrence rn ON rn.negotiate = n.id
        JOIN purchase purchase ON purchase.id = n.purchase
        WHERE n.subscription = a.id
            AND rn.recurrence = r.rec_num
            AND purchase.status IN ('VALID','FILED')
    )
    AND r.rec_num NOT IN (
        SELECT r2.rec_num
        FROM purchase c2
        JOIN recurrency r2 ON c2.id_recurrency = r2.id
        JOIN item_product ip2 ON c2.item_estoque = ip2.id
        WHERE ip2.signature = a.id
            AND c2.status IN ('VALID','FILED')
    )
    AND c.id NOT IN (
        SELECT n1.purchase
        FROM negotiate n1
        WHERE n1.subscription = a.id
    )
    AND c.status = 'DELAYED'
    -- 核心条件:匹配当前rec_num下的最大due_date
    AND c.due_date = (
        SELECT MAX(c2.due_date)
        FROM purchase c2
        JOIN recurrency r2 ON c2.id_recurrency = r2.id
        JOIN item_product ip2 ON c2.item_estoque = ip2.id
        JOIN signature a2 ON a2.id = ip2.signature
        WHERE a2.id = :id
            AND r2.rec_num = r.rec_num
            AND r2.plano_signature IS NOT NULL
            AND r2.rec_num IN (1,2,3,4)
            AND r2.rec_num NOT IN (
                SELECT rn.recurrence
                FROM negotiate n
                JOIN negotiate_recurrence rn ON rn.negotiate = n.id
                JOIN purchase purchase ON purchase.id = n.purchase
                WHERE n.subscription = a2.id
                    AND rn.recurrence = r2.rec_num
                    AND purchase.status IN ('VALID','FILED')
            )
            AND r2.rec_num NOT IN (
                SELECT r3.rec_num
                FROM purchase c3
                JOIN recurrency r3 ON c3.id_recurrency = r3.id
                JOIN item_product ip3 ON c3.item_estoque = ip3.id
                WHERE ip3.signature = a2.id
                    AND c3.status IN ('VALID','FILED')
            )
            AND c2.id NOT IN (
                SELECT n1.purchase
                FROM negotiate n1
                WHERE n1.subscription = a2.id
            )
            AND c2.status = 'DELAYED'
    );

简化版(复用原始查询作为子查询)

如果不想重复写条件,也可以把原始查询封装为子查询,再关联获取分组最大日期的结果:

SELECT t.*
FROM (
    -- 原始查询
    SELECT 
        r.rec_num as Column_A
        ,c.amount as Column_B
        ,c.status as Column_C
        ,c.currency_code_to as Column_D
        ,c.due_date as Column_E
        ,c.id_recurrency as Column_F
    FROM purchase c
    JOIN recurrency r ON c.id_recurrency = r.id
    JOIN item_product ip ON c.item_estoque = ip.id
    JOIN signature a ON a.id = ip.signature
    WHERE a.id = :id
        AND r.plano_signature IS NOT NULL
        AND r.rec_num IN (1,2,3,4)
        AND r.rec_num NOT IN (
            SELECT rn.recurrence
            FROM negotiate n
            JOIN negotiate_recurrence rn ON rn.negotiate = n.id
            JOIN purchase purchase ON purchase.id = n.purchase
            WHERE n.subscription = a.id
                AND rn.recurrence = r.rec_num
                AND purchase.status IN ('VALID','FILED')
        )
        AND r.rec_num NOT IN (
            SELECT r2.rec_num
            FROM purchase c2
            JOIN recurrency r2 ON c2.id_recurrency = r2.id
            JOIN item_product ip2 ON c2.item_estoque = ip2.id
            WHERE ip2.signature = a.id
                AND c2.status IN ('VALID','FILED')
        )
        AND c.id NOT IN (
            SELECT n1.purchase
            FROM negotiate n1
            WHERE n1.subscription = a.id
        )
        AND c.status = 'DELAYED'
) t
INNER JOIN (
    -- 获取每个rec_num的最大due_date
    SELECT Column_A, MAX(Column_E) AS max_due_date
    FROM (
        SELECT 
            r.rec_num as Column_A
            ,c.due_date as Column_E
        FROM purchase c
        JOIN recurrency r ON c.id_recurrency = r.id
        JOIN item_product ip ON c.item_estoque = ip.id
        JOIN signature a ON a.id = ip.signature
        WHERE a.id = :id
            AND r.plano_signature IS NOT NULL
            AND r.rec_num IN (1,2,3,4)
            AND r.rec_num NOT IN (
                SELECT rn.recurrence
                FROM negotiate n
                JOIN negotiate_recurrence rn ON rn.negotiate = n.id
                JOIN purchase purchase ON purchase.id = n.purchase
                WHERE n.subscription = a.id
                    AND rn.recurrence = r.rec_num
                    AND purchase.status IN ('VALID','FILED')
            )
            AND r.rec_num NOT IN (
                SELECT r2.rec_num
                FROM purchase c2
                JOIN recurrency r2 ON c2.id_recurrency = r2.id
                JOIN item_product ip2 ON c2.item_estoque = ip2.id
                WHERE ip2.signature = a.id
                    AND c2.status IN ('VALID','FILED')
            )
            AND c.id NOT IN (
                SELECT n1.purchase
                FROM negotiate n1
                WHERE n1.subscription = a.id
            )
            AND c.status = 'DELAYED'
    ) t2
    GROUP BY Column_A
) t3 ON t.Column_A = t3.Column_A AND t.Column_E = t3.max_due_date;

内容的提问来源于stack exchange,提问作者Patrick de Souza Teixeira

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 14:07:03