"小王盯着屏幕上的客户数据表发愁——老板要他‘找出每个地区最早注册的客户’,但他连‘最早’这个词在SQL里怎么表达都拿不准..." 如果你也遇到过类似困扰,今天我们就用最接地气的方式,彻底讲透SQL中处理"第一条记录"的N种姿势。
想象你正在分析:
这些场景都需要锁定"第一条"数据,但有趣的是,标准SQL中其实并没有FIRST()
函数(MySQL/MariaDB除外),这就像去餐厅点菜发现菜单上没有"红烧肉",但厨师会说"我们有糖醋排骨啊"。
-- 找出每个部门最早入职的员工 WITH ranked_employees AS ( SELECT employee_name, department, hire_date, ROW_NUMBER() OVER (PARTITION BY department ORDER BY hire_date) AS rn FROM employees ) SELECT * FROM ranked_employees WHERE rn = 1;
原理:先给每个部门的员工按入职日期排序标号,再筛选1号选手,适用于PostgreSQL、SQL Server、Oracle等现代数据库。
-- 获取每个商品类别的首次上架记录 SELECT DISTINCT product_category, FIRST_VALUE(product_name) OVER ( PARTITION BY product_category ORDER BY launch_date ) AS first_product FROM products;
注意:这里必须用DISTINCT
去重,否则会返回所有记录。
-- SQLite/早期MySQL中找每个用户的首笔订单 SELECT o.* FROM orders o JOIN ( SELECT user_id, MIN(order_date) AS first_order_date FROM orders GROUP BY user_id ) first ON o.user_id = first.user_id AND o.order_date = first.first_order_date;
缺陷:如果同一用户同秒有多个订单,会全部返回。
NULL值陷阱
当排序字段包含NULL时:
ORDER BY create_time DESC NULLS LAST -- PostgreSQL语法 ORDER BY IFNULL(create_time, '9999-12-31') -- MySQL写法
并列第一处理
用RANK()
代替ROW_NUMBER()
会保留并列记录:
RANK() OVER (ORDER BY score DESC) -- 两个100分都排第1
性能优化
大数据量时,给分区字段和排序字段加联合索引:
CREATE INDEX idx_dept_hire ON employees(department, hire_date);
▶ 随机取第一条(抽奖场景)
-- PostgreSQL的TABLESAMPLE用法 SELECT * FROM users TABLESAMPLE SYSTEM(1) LIMIT 1;
▶ 按自定义顺序取首条
-- 优先显示状态为'active'的记录 SELECT * FROM ( SELECT *, ROW_NUMBER() OVER ( ORDER BY CASE status WHEN 'active' THEN 0 ELSE 1 END, create_time ) AS rn FROM tickets ) t WHERE rn = 1;
LATERAL JOIN黑科技(PostgreSQL)
-- 查询每个订单的首个操作日志 SELECT o.order_id, first_log.* FROM orders o CROSS JOIN LATERAL ( SELECT * FROM order_logs WHERE order_id = o.order_id ORDER BY log_time LIMIT 1 ) first_log;
DISTINCT ON语法(PostgreSQL独家)
-- 简洁版分组取首条 SELECT DISTINCT ON (department) * FROM employees ORDER BY department, hire_date;
最新实践建议(2025):随着SQL:2023标准的普及,更多数据库开始支持QUALIFY
子句,未来可能简化为:
SELECT * FROM sales QUALIFY ROW_NUMBER() OVER(PARTITION BY region ORDER BY sale_date) = 1;
没有最好的方法,只有最适合当前数据库版本和数据特征的写法,下次当你需要"第一条"数据时,不妨把这篇文章当作速查手册。
本文由 镜谷蓝 于2025-07-30发表在【云服务器提供商】,文中图片由(镜谷蓝)上传,本平台仅提供信息存储服务;作者观点、意见不代表本站立场,如有侵权,请联系我们删除;若有图片侵权,请您准备原始证明材料和公证书后联系我方删除!
本文链接:https://vps.7tqx.com/wenda/488308.html
发表评论