上一篇
📢最新动态
根据2025年8月数据库技术调研显示,超过78%的数据分析师在日常工作中需要处理"获取每个分组最新记录"的场景,这已成为SQL查询中最常遇到的挑战之一!
假设我们有一个订单表orders
,需要找出每个客户最近的一笔订单:
CREATE TABLE orders ( order_id INT, customer_id INT, order_date DATE, amount DECIMAL(10,2) );
WITH ranked_orders AS ( SELECT *, ROW_NUMBER() OVER (PARTITION BY customer_id ORDER BY order_date DESC) AS rn FROM orders ) SELECT order_id, customer_id, order_date, amount FROM ranked_orders WHERE rn = 1;
✅ 优点:清晰高效,现代数据库都支持
❌ 缺点:MySQL 5.7以下版本不支持
SELECT DISTINCT ON (customer_id) * FROM orders ORDER BY customer_id, order_date DESC;
✅ 优点:语法简洁
❌ 缺点:仅限PostgreSQL
SELECT o.* FROM orders o JOIN ( SELECT customer_id, MAX(order_date) AS latest_date FROM orders GROUP BY customer_id ) latest ON o.customer_id = latest.customer_id AND o.order_date = latest.latest_date;
⚠️ 注意:如果同一客户同一天有多笔订单,会返回多条记录
SELECT o.* FROM (SELECT DISTINCT customer_id FROM orders) c JOIN LATERAL ( SELECT * FROM orders WHERE customer_id = c.customer_id ORDER BY order_date DESC LIMIT 1 ) o ON true;
SELECT o1.* FROM orders o1 WHERE NOT EXISTS ( SELECT 1 FROM orders o2 WHERE o2.customer_id = o1.customer_id AND o2.order_date > o1.order_date );
方法 | 可读性 | 性能 | 适用数据库 |
---|---|---|---|
ROW_NUMBER() | 主流数据库 | ||
DISTINCT ON | PostgreSQL | ||
自连接 | 所有数据库 | ||
LATERAL JOIN | MySQL 8.0+ | ||
NOT EXISTS | 所有数据库 |
ROW_NUMBER()
或DISTINCT ON
ORDER BY order_date DESC, order_id DESC
某电商平台在2025年Q2使用ROW_NUMBER()
优化了会员消费分析查询,使查询速度从原来的14秒提升到0.8秒!
-- 找出每个会员消费金额最高的订单 WITH ranked_orders AS ( SELECT *, ROW_NUMBER() OVER ( PARTITION BY customer_id ORDER BY amount DESC, order_date DESC ) AS rn FROM orders WHERE order_date >= '2025-01-01' ) SELECT * FROM ranked_orders WHERE rn = 1;
掌握这些技巧,你就能轻松应对各种"获取最新记录"的业务场景啦!🎯 下次产品经理再要这类报表,分分钟搞定~
本文由 蹇武 于2025-08-01发表在【云服务器提供商】,文中图片由(蹇武)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://vps.7tqx.com/wenda/500550.html
发表评论