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

MySQL 5.5单表查询如何按客户分组获取最新2条符合条件订单

解决方案

你需要通过窗口函数给同个客户的订单按时间排序打标,再筛选排名前2的记录即可,以下是可直接使用的实现:

通用写法(支持MySQL 8.0+、PostgreSQL、SQL Server等主流数据库)

SELECT 
    CustomerId,
    Id
FROM (
    SELECT 
        CustomerId,
        Id,
        ROW_NUMBER() OVER (
            PARTITION BY CustomerId 
            ORDER BY DateOfOrder DESC, Id DESC
        ) AS row_rank
    FROM `order`
    WHERE 
        `Order` = 'Merchandise'
        AND DateOfOrder >= '2018-01-01'
) AS ranked_orders
WHERE row_rank <= 2;

写法说明

  • 核心用ROW_NUMBER()窗口函数,PARTITION BY CustomerId实现按客户维度分组,组内按DateOfOrder倒序、同日期按主键Id倒序(避免同天订单排序混乱)生成排名序号
  • 把原SQL中year(o.DateOfOrder)>= 2018调整为DateOfOrder >= '2018-01-01',避免对字段做函数运算导致无法命中DateOfOrder字段的索引,大幅提升大表查询性能
  • 由于order是SQL保留关键字,作为表名、字段名使用时需要根据数据库类型做转义:MySQL用反引号包裹,PostgreSQL用双引号包裹,SQL Server用方括号包裹,避免语法报错

兼容写法(适用于不支持窗口函数的MySQL 5.x等老版本数据库)

如果你的数据库版本不支持窗口函数,可以用关联子查询实现相同逻辑:

SELECT 
    o1.CustomerId,
    o1.Id
FROM `order` o1
WHERE 
    o1.`Order` = 'Merchandise'
    AND o1.DateOfOrder >= '2018-01-01'
    AND (
        SELECT COUNT(*)
        FROM `order` o2
        WHERE 
            o2.CustomerId = o1.CustomerId
            AND o2.`Order` = 'Merchandise'
            AND o2.DateOfOrder >= '2018-01-01'
            AND (
                o2.DateOfOrder > o1.DateOfOrder 
                OR (o2.DateOfOrder = o1.DateOfOrder AND o2.Id > o1.Id)
            )
    ) < 2
ORDER BY o1.CustomerId, o1.DateOfOrder DESC;

写法说明

该逻辑通过子查询统计同客户下比当前订单更新的符合条件的订单数,数量小于2即代表当前订单属于该客户最新的2条订单。该写法在数据量较大时性能弱于窗口函数写法,优先选择窗口函数版本。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 14:54:38