随便聊聊那些用得上的随机SQL函数,举几个简单例子看看效果
- 问答
- 2026-01-09 06:19:31
- 5
给数据排排坐,标个号:ROW_NUMBER() 和它的兄弟们
这个功能在数据分析的时候特别有用,想象一下,你有一张学生成绩表,你想知道每个学生在自己班级里的排名,或者你想对一组数据按顺序标上1、2、3……这时候ROW_NUMBER()就登场了。
它通常和OVER这个关键字一起用。OVER后面跟着的,就是告诉数据库怎么给数据“分组”和怎么“排序”。
-
例子1:简单的顺序编号 假设我们有一张
orders订单表,我们想按照订单创建的时间先后,给所有订单编个号。SELECT order_id, order_date, ROW_NUMBER() OVER (ORDER BY order_date ASC) as order_sequence FROM orders;这样查询结果就会多出一列
order_sequence,从1开始,按照order_date从早到晚依次递增。 -
例子2:组内排名 现在需求升级了,我们有一张
sales销售表,里面有销售员、销售部门和销售额,我们想看看每个销售部门里,谁的业绩最好。 这里就要用到PARTITION BY,它是在OVER里面用来分组的。
SELECT salesperson, department, sales_amount, ROW_NUMBER() OVER (PARTITION BY department ORDER BY sales_amount DESC) as dept_rank FROM sales;这个查询的意思就是:先按
department部门进行分组,然后在每个部门内部,按照sales_amount销售额从高到低排序,最后给每个人标上排名,排名第一的,就是部门的销售冠军。除了
ROW_NUMBER(),它还有两个兄弟:RANK()和DENSE_RANK(),它们的区别在于处理并列名次的方式:ROW_NUMBER():即使成绩相同,也会给出连续的号码(1,2,3,4)。RANK():如果两人销售额相同,并列第一,那么下一个名次就是第三(1,1,3,4)。DENSE_RANK():如果两人销售额相同,并列第一,那么下一个名次是第二(1,1,2,3)。
看一眼上一行或下一行的数据:LAG() 和 LEAD()
这两个函数非常强大,可以用来做环比、同比分析,它们能在当前行,直接获取到前面一行或者后面一行的数据,而不用去写复杂的自连接查询。
- 例子:计算月度销售额的环比增长
假设有张
monthly_sales表,有月份和当月销售额,我们想计算每个月的销售额比上个月增长了多少。SELECT month, sales_amount, LAG(sales_amount, 1) OVER (ORDER BY month) as previous_month_sales, -- 获取上个月的数据 (sales_amount - LAG(sales_amount, 1) OVER (ORDER BY month)) / LAG(sales_amount, 1) OVER (ORDER BY month) * 100 as growth_rate FROM monthly_sales;LAG(sales_amount, 1)中的1表示向前看1行,同样,LEAD()就是向后看,这样我们就能轻松地拿到相邻月份的数据进行计算了,对于第一个月,LAG()会返回NULL,所以增长率也是NULL,这很合理。
把多行数据“捏”到一起:STRING_AGG() (或 GROUP_CONCAT())
这个函数特别直观,有时候你分组查询后,不想只显示一个汇总值,而是想把组内的某些文本值都罗列出来,用逗号或者其他符号隔开。
-
例子:查看每个部门的所有员工姓名 有一张
employees表,有员工姓名和部门,我们想得到一个结果,第一列是部门名,第二列是这个部门所有员工的名字,用顿号隔开。-- 在MySQL中可能是GROUP_CONCAT -- SELECT department, GROUP_CONCAT(employee_name SEPARATOR '、') FROM employees GROUP BY department; -- 在SQL Server或PostgreSQL中常用STRING_AGG SELECT department, STRING_AGG(employee_name, '、') WITHIN GROUP (ORDER BY employee_name) as employee_list FROM employees GROUP BY department;结果可能就是这样: | department | employee_list | |------------|----------------| | 技术部 | 张三、李四、王五 | | 市场部 | 赵六、孙七 |
这样看起来就非常清晰明了。

处理空值的“替补队员”:COALESCE()
这个函数非常简单实用,它接受多个参数,返回第一个不是NULL的值,就像准备了好几个替补队员,第一个不上第二个上。
- 例子:显示用户的联系方式
用户表
users中,可能有手机号phone和备用邮箱backup_email,但有些字段是空的,我们想优先显示手机号,如果手机号为空,就显示备用邮箱,如果都为空,就显示“暂无联系方式”。SELECT user_name, COALESCE(phone, backup_email, '暂无联系方式') as contact_info FROM users;这样就能保证
contact_info这一列永远有一个可读的值,而不是令人困惑的NULL。
条件判断:CASE WHEN ... THEN ... END
这大概是SQL里最像编程语言中if-else语句的结构了,用途极其广泛,它允许你根据不同的条件,返回不同的值。
- 例子:给销售额分级
还是销售表,我们想根据销售额的大小,给每笔销售打上一个标签。
SELECT salesperson, sales_amount, CASE WHEN sales_amount > 10000 THEN '优秀' WHEN sales_amount BETWEEN 5000 AND 10000 THEN '良好' WHEN sales_amount BETWEEN 1000 AND 4999 THEN '及格' ELSE '需努力' END as performance_level FROM sales;这种灵活的判断能力,在数据清洗、打标签、生成报表等场景下简直是神器。
这些函数只是SQL强大功能的一个缩影,它们的特点都是“想法很直接,效果很显著”,平时多了解一下,等真正遇到合适的场景时,你就会想起来:“哎,好像有个函数正好能搞定这个!”,然后事半功倍,希望这几个简单的例子能让你觉得有点意思。
本文由芮以莲于2026-01-09发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/77275.html
