SQL Server 2017:获取各锻炼动作首次创纪录重量的日期
解决方案
可以通过先获取每个动作的最大重量,再关联原表筛选首次达到该重量的日期,或者使用窗口函数精准定位目标记录,以下是两种可行的实现方式:
方法一:子查询关联法
SELECT MIN(f.Date) AS first_record_date, f.Exercise, pr.personal_record FROM table..fitness f INNER JOIN ( -- 先计算每个动作的个人最大重量 SELECT Exercise, MAX(Weight_kg) AS personal_record FROM table..fitness WHERE Date >= '2022-01-01' AND Weight_kg > 1 GROUP BY Exercise ) pr ON f.Exercise = pr.Exercise AND f.Weight_kg = pr.personal_record WHERE f.Date >= '2022-01-01' AND f.Weight_kg > 1 GROUP BY f.Exercise, pr.personal_record ORDER BY pr.personal_record DESC
方法二:窗口函数筛选法
WITH ranked_records AS ( SELECT Date, Exercise, Weight_kg, -- 对每个动作达到最大重量的记录按日期排序,标记首次出现的记录 ROW_NUMBER() OVER ( PARTITION BY Exercise ORDER BY Date ASC ) AS rn FROM table..fitness WHERE Date >= '2022-01-01' AND Weight_kg > 1 -- 仅保留达到该动作最大重量的记录 AND Weight_kg = ( SELECT MAX(Weight_kg) FROM table..fitness sub WHERE sub.Exercise = table..fitness.Exercise AND sub.Date >= '2022-01-01' AND sub.Weight_kg > 1 ) ) SELECT Date AS first_record_date, Exercise, Weight_kg AS personal_record FROM ranked_records WHERE rn = 1 ORDER BY personal_record DESC
之前方法失败的原因说明
- 窗口函数+GROUP BY的逻辑冲突:你在窗口函数中计算了分组累计最大值,但后续又用GROUP BY对日期和动作分组,导致结果包含所有训练日期的记录,没有精准筛选首次达到全局最大值的条目。
- 直接MIN(Date)分组:你对动作的所有记录取最小日期,没有限定在达到最大重量的记录范围内,因此得到的是动作首次训练的日期,而非创纪录日期。
- ROW_NUMBER()的错误用法:子查询中对所有记录加行号,没有先筛选出达到最大重量的记录,且外层的GROUP BY属于多余操作,导致语法报错且逻辑偏离目标。
内容的提问来源于stack exchange,提问作者dr.pas
相关产品推荐
相关产品推荐

