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

如何在现有SQL分组查询中筛选每组最大DueDate的记录?

解决方法:筛选每个客户对应最大DueDate的记录

哈哈,这个问题我刚入行的时候也踩过坑!直接写WHERE cs.DueDate = MAX(cs.DueDate)肯定不行——因为数据库在执行WHERE子句时,还没完成分组和聚合计算,根本不知道MAX(cs.DueDate)的具体值,会直接抛出语法错误。下面给你两种实用的解决方案:

方案一:子查询+关联筛选(适合大多数SQL数据库)

先通过子查询算出每个客户对应的最大DueDate,再用这个结果关联T_ClientStore表,只保留匹配最大DueDate的记录,最后再执行原有的关联和聚合逻辑:

SELECT 
    cl.[Name] Client, 
    bt.Name BottleType, 
    SUM(csi.Amount) Amount 
FROM 
    T_Clients cl 
-- 子查询获取每个客户的最大DueDate
INNER JOIN (
    SELECT FK_ClientId, MAX(DueDate) AS MaxDueDate
    FROM T_ClientStore
    GROUP BY FK_ClientId
) cs_max ON cs_max.FK_ClientId = cl.ClientID
-- 筛选出该客户对应最大DueDate的门店记录
INNER JOIN T_ClientStore cs 
    ON cs.FK_ClientId = cl.ClientID 
    AND cs.DueDate = cs_max.MaxDueDate
INNER JOIN T_ClientStoreItem csi ON csi.FK_ClientStoreId = cs.ClientStoreId 
INNER JOIN T_BottleType bt ON bt.BottleTypeId = csi.FK_BootleTypeID 
GROUP BY 
    cl.[Name], bt.Name 
ORDER BY 
    cl.[Name]

方案二:窗口函数标记法(适合支持窗口函数的数据库,如SQL Server、MySQL 8+、PostgreSQL等)

用RANK()或ROW_NUMBER()窗口函数给每个客户的门店记录按DueDate降序排名,只保留排名为1的记录(也就是最大DueDate的那些):

WITH ClientStoreWithRank AS (
    SELECT 
        cs.ClientStoreId,
        cs.FK_ClientId,
        -- 按客户分组,DueDate降序排名,最大的日期排名为1
        RANK() OVER (PARTITION BY cs.FK_ClientId ORDER BY cs.DueDate DESC) AS DateRank
    FROM T_ClientStore cs
)
SELECT 
    cl.[Name] Client, 
    bt.Name BottleType, 
    SUM(csi.Amount) Amount 
FROM 
    T_Clients cl 
-- 只保留每个客户排名第一的门店记录
INNER JOIN ClientStoreWithRank cs_r 
    ON cs_r.FK_ClientId = cl.ClientID 
    AND cs_r.DateRank = 1
INNER JOIN T_ClientStore cs ON cs.ClientStoreId = cs_r.ClientStoreId
INNER JOIN T_ClientStoreItem csi ON csi.FK_ClientStoreId = cs.ClientStoreId 
INNER JOIN T_BottleType bt ON bt.BottleTypeId = csi.FK_BootleTypeID 
GROUP BY 
    cl.[Name], bt.Name 
ORDER BY 
    cl.[Name]

小提示:

  • 如果一个客户可能有多个门店记录的DueDate都是最大值(比如同一天的多个门店),用RANK()会保留所有这些记录;如果只想随机保留一条,换成ROW_NUMBER()即可。
  • 不要用HAVING子句来处理这个需求——HAVING是用来筛选分组后的聚合结果(比如筛选SUM(Amount) > 100的分组),而我们需要的是在分组前就筛选出符合条件的行,所以HAVING不适用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 12:57:29