如何以产品名称为筛选条件,按日期查询倒数第二条记录?
解决按产品筛选查询倒数第二条记录日期的问题
嘿,我懂你现在遇到的困境——要针对特定产品,找出倒数第二个有记录的日期对应的所有条目,之前用DISTINCT拿到了那个目标日期,但把产品筛选条件整合进去的时候就卡壳了对吧?别担心,咱们用窗口函数就能完美解决这个需求,而且逻辑更清晰,还能直接拿到同一日期下的所有记录。
核心思路拆解
你的需求本质是两步:
- 第一步:针对指定产品,找到日期维度的倒数第二个存在记录的日期(不是单条记录的倒数第二,是日期层面的倒数第二)
- 第二步:获取该日期下该产品的所有原始记录(毕竟同一日期有多条是正常逻辑)
方案一:先去重日期再关联(兼容所有支持CTE的数据库)
这种方式先明确拿到每个产品的唯一日期列表,再给日期排名,最后关联原表拿全量记录:
WITH ranked_dates AS ( SELECT product_name, record_date, -- 按产品分组,日期降序排名,最新日期排1,倒数第二排2 ROW_NUMBER() OVER (PARTITION BY product_name ORDER BY record_date DESC) AS date_rank FROM ( -- 先提取每个产品的唯一日期 SELECT DISTINCT product_name, record_date FROM your_table_name ) AS distinct_dates ) -- 关联原表拿到目标日期下的所有记录 SELECT t.* FROM your_table_name t JOIN ranked_dates rd ON t.product_name = rd.product_name AND t.record_date = rd.record_date WHERE rd.product_name = '你的目标产品名称' -- 替换成要筛选的产品 AND rd.date_rank = 2;
方案二:直接用DENSE_RANK简化逻辑(更高效)
如果你的数据库支持窗口函数,用DENSE_RANK()可以省去先去重的步骤,直接给同一日期的所有记录分配相同的排名:
WITH product_date_ranks AS ( SELECT *, -- 按产品分组,日期降序排名,同一日期的所有记录排名相同 DENSE_RANK() OVER (PARTITION BY product_name ORDER BY record_date DESC) AS date_rank FROM your_table_name ) SELECT * FROM product_date_ranks WHERE product_name = '你的目标产品名称' -- 替换成要筛选的产品 AND date_rank = 2;
为什么用DENSE_RANK?
ROW_NUMBER()会给同一日期的不同记录分配不同的排名,而DENSE_RANK()会让同一日期的所有记录共享同一个排名,刚好符合我们“按日期维度找倒数第二”的需求,不用额外去重,代码更简洁高效。
注意事项
- 记得把代码里的
your_table_name替换成你的实际表名 '你的目标产品名称'替换成你要筛选的具体产品名称- 如果你的数据库不支持CTE(比如老版本MySQL),可以把CTE改成子查询嵌套的形式,逻辑是一样的
内容的提问来源于stack exchange,提问作者Federico Martinez
相关产品推荐
相关产品推荐

