上一篇我们讨论了如何利用 FETCH(或者 LIMIT)和 OFFSET 实现数据的 Top-N 排行榜和分页查询。
SQL 语句主要的功能就是对数据进行处理和分析。为了避免重复造轮子,提高数据处理的效率,SQL 为我们提供了许多标准的功能模块:函数(Function)。实际上我们已经使用过 SQL 函数,例如将字符转换为大写形式的 UPPER 函数。
函数概述
SQL 函数是一种具有某种功能的模块,可以接收零个或多个输入值,并且返回一个输出值。函数处理数据的过程如下图所示:
在 SQL 中,函数主要分为两种类型:
- 标量函数(scalar function)。标量函数针对每个输入参数,返回一个输出结果。例如,ABS(x) 可以计算 x 的绝对值。
- 聚合函数(aggregate function)。聚合函数基于一组数据进行计算,返回一个输出结果。例如,AVG 函数可以计算一组数据的平均值。
我们先介绍标量函数,聚合函数将会在第 12 篇中进行介绍。为了方便学习,我们将常见的 SQL 标量函数分为以下几类:数值函数、字符函数、日期函数以及类型转换函数。本篇只涉及数值函数。
数值函数
数值函数通常接收数字类型的参数,执行数学计算并返回一个数值结果。以下是 SQL 中常见的数值函数及不同数据库中的实现:
函数 | 描述 | Oracle | MySQL | SQL Server | PostgreSQL |
---|---|---|---|---|---|
ABS(x) | 计算 x 的绝对值 | 支持 | 支持 | 支持 | 支持 |
CEIL(x) / CEILING(x) | 计算大于等于 x 的最小整数 | 支持 CEIL(x) | 支持 | 支持 CEILING(x) | 支持 |
EXP(x) | 计算 e 的 x 次幂,e 约等于 2.71828 | 支持 | 支持 | 支持 | 支持 |
FLOOR(x) | 计算小于等于 x 的最大整数 | 支持 | 支持 | 支持 | 支持 |
LN(x) | 计算 x 的自然对数,底数为 e | 支持 | 支持 | LOG(x) | 支持 |
LOG(y, x) | 计算以 y 为底的 x 的对数 | 支持 | 支持 | LOG(x, y) | 支持 |
MOD(x, y) | 计算 x 除以 y 的余数,即求模运算 | 支持 | 支持 | x % y | 支持 |
POWER(x, y) | 计算 x 的 y 次幂 | 支持 | 支持 | 支持 | 支持 |
ROUND(x, y) | 将 x 四舍五入到 y 位小数 | 支持 | 支持 | 支持 | 支持 |
SQRT(x) | 计算 x 的平方根 | 支持 | 支持 | 支持 | 支持 |
GREAST(x, y, …) | 计算参数列表中的最大值 | 支持 | 支持 | 不支持 | 支持 |
LEAST(x, y, …) | 计算参数列表中的最小值 | 支持 | 支持 | 不支持 | 支持 |
RANDOM( ) | 返回一个大于等于 0 小于 1 的随机数 | DBMS_RANDOM.VALUE | RAND() | RAND() | 支持 |
绝对值函数
ABS 函数计算输入参数的绝对值:
SELECT ABS(-2), ABS(2) FROM employee WHERE emp_id = 1;
ABS(-2)|ABS(2)| -------|------| 2| 2|
取整函数
CEIL 和 CEILING 函数向上取整,FLOOR 函数向下取整,ROUND 函数执行四舍五入运算:
SELECT CEIL(1.9), -- SQL Server 使用 CEILING(1.9) FLOOR(4.5), ROUND(9.456, 1) FROM employee WHERE emp_id = 1;
CEIL(1.9)|FLOOR(4.5)|ROUND(9.456, 1)|
---------|----------|---------------|
2| 4| 9.5|
1.9 向上取整为 2,4.5 向下取整为 4,9.456 四舍五入到一位小数得到 9.5。
Oracle 只实现了 CEIL 函数,SQL Server 只实现了 CEILING 函数。
指数函数
EXP 函数计算自然常数 e 的 N 次方,POWER 函数计算指定底数的 N 次方:
SELECT EXP(1), POWER(2, 4) FROM employee WHERE emp_id = 1;
EXP(1) |POWER(2, 4)|
-----------------|-----------|
2.718281828459045| 16|
自然常数 e 约等于 2.71828,2 的 4 次方等于 16。
对数函数
LN 函数计算以 e 为底的自然对数,LOG 函数计算指定底数的对数:
-- Oracle、MySQL 以及 PostgreSQL 实现
SELECT LOG(6, 36), LN(2.7182818285) FROM employee WHERE emp_id = 1;
-- SQL Server 实现
SELECT LOG(36, 6), LOG(2.7182818285) FROM employee WHERE emp_id = 1;
该查询的结果如下:
LOG(6, 36)|LN(2.7182818285)|
----------|----------------|
2| 1|
SQL Server 中对数函数的实现有所不同,它使用 LOG(x) 计算 x 的自然对数 LN(x);并且使用 LOG(x, y) 计算以 y 为底的 x 的对数,其他数据库使用 LOG(y, x)。
平方根函数
SQRT 函数计算数据的平方根:
SELECT SQRT(25) FROM employee WHERE emp_id = 1;
SQRT(25)|
--------|
5|
求余函数
MOD 函数用于计算两个数相除的余数:
— Oracle、MySQL 以及 PostgreSQL 实现 SELECT MOD(7,3) FROM employee WHERE empid = 1; MOD(7,3)| ————| 1| — MySQL、SQL Server 以及 PostgreSQL 实现 SELECT 7 % 3 FROM employee WHERE emp_id = 1; 7 % 3| ——-|_ 1| 复制
7 除以 3 的余数是 1。SQL Server 使用 % 运算符进行求余运算,MySQL 和 PostgreSQL 也支持 % 运算符。
最大值与最小值
GREAST 和 LEAST 函数分别计算参数列表中的最大值和最小值:
-- Oracle、MySQL 以及 PostgreSQL 实现
SELECT GREATEST(1, 2, 3), LEAST(1, 2, 3) FROM employee WHERE emp_id = 1;
GREATEST(1, 2, 3)|LEAST(1, 2, 3)|
-----------------|--------------|
3| 1|
1、2、3 中最大的是 3,最小的是 1。SQL Server 目前没有提供这两个函数。
生成随机数
生成随机数的函数在各种数据库中的实现不同:
-- MySQL 和 SQL Server 实现
SELECT RAND() FROM employee WHERE emp_id = 1;
RAND() |
------------------|
0.8572325947296178|
-- Oracle 实现
SELECT DBMS_RANDOM.VALUE FROM employee WHERE emp_id = 1;
VALUE |
----------------------------------------|
0.33095309998157211073097228949436162842|
-- PostgreSQL 实现
SELECT RANDOM() FROM employee WHERE emp_id = 1;
random |
------------------|
0.7409744057804346|
随机数函数每次都会返回不同的结果,所以你的结果应该和上面的数据并不相同。
其他常见的数值函数还有三角函数,例如 sin(x)、cos(x) 等。它们都是一些通用的数学函数,需要时可以查看数据库相关的文档。
小结
掌握常见的 SQL 函数将会方便我们进行数据的处理和分析,避免重复实现已有的功能。本篇主要介绍了常见的数值函数,大多数函数都可以在不同的数据库之间通用,但是也存在一些数据库专有的函数实现。
思考题:如何实现查询语句,每次执行时从员工表中返回随机的 5 条不同的数据?