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

MySQL跨多表查询每个客户第N条库存移动记录的创建日期

解决方案:用窗口函数实现分组取第N条记录

这是库存管理场景里很常见的分组排名需求,MySQL 8.0及以上版本提供的窗口函数能完美解决这个问题。咱们直接上可行方案,再拆解细节:

核心思路

  1. 关联三张表:通过tableProduct作为中间桥梁,把tableCustomer和tableMovement关联起来,让每条库存移动记录都对应到所属客户。
  2. 分组排名:用ROW_NUMBER()窗口函数,按客户ID分组,给每个客户的移动记录按创建日期(或你需要的业务规则)排序并编号。
  3. 筛选目标记录:从排名结果中挑选出编号等于N的记录,就是每个客户的第N条库存移动记录。

具体SQL代码(以N=25为例)

WITH ranked_movements AS (
    SELECT 
        c.customerID,
        m.createDate,
        -- 按客户分组,移动记录按创建日期升序排名
        ROW_NUMBER() OVER (
            PARTITION BY c.customerID 
            ORDER BY m.createDate ASC
        ) AS movement_rank
    FROM tableCustomer c
    -- 关联产品表:匹配客户名下的所有产品
    JOIN tableProduct p ON c.customerID = p.customerID
    -- 关联移动记录表:匹配产品对应的所有库存移动记录
    JOIN tableMovement m ON p.productID = m.productID
)
-- 筛选出每个客户的第25条移动记录
SELECT customerID, createDate
FROM ranked_movements
WHERE movement_rank = 25;

关键细节调整

  • 排序规则自定义:如果你的业务需要取「最新的第N条」而非「最早的第N条」,把ORDER BY m.createDate ASC改成ORDER BY m.createDate DESC即可。
  • 处理记录不足N条的客户:如果想保留那些移动记录少于N条的客户(对应createDate显示为NULL),把JOIN换成LEFT JOIN,确保所有客户都被包含:
WITH ranked_movements AS (
    SELECT 
        c.customerID,
        m.createDate,
        ROW_NUMBER() OVER (
            PARTITION BY c.customerID 
            ORDER BY m.createDate ASC
        ) AS movement_rank
    FROM tableCustomer c
    LEFT JOIN tableProduct p ON c.customerID = p.customerID
    LEFT JOIN tableMovement m ON p.productID = m.productID
)
SELECT customerID, createDate
FROM ranked_movements
WHERE movement_rank = 25;

验证你的示例数据

当N=1时,用你提供的示例数据运行代码,会得到完全符合期望的结果:

customerIDcreateDate
1232020-01-25
1242020-01-28

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 13:22:58