上一篇我们讨论了如何利用 FETCH(或者 LIMIT)和 OFFSET 实现数据的 Top-N 排行榜和分页查询。
SQL 语句主要的功能就是对数据进行处理和分析。为了避免重复造轮子,提高数据处理的效率,SQL 为我们提供了许多标准的功能模块:函数(Function)。实际上我们已经使用过 SQL 函数,例如将字符转换为大写形式的 UPPER 函数。

函数概述

SQL 函数是一种具有某种功能的模块,可以接收零个或多个输入值,并且返回一个输出值。函数处理数据的过程如下图所示:
八、什么是函数?如何利用函数提高数值计算的效率? - 图1
在 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 函数计算输入参数的绝对值:

  1. SELECT ABS(-2), ABS(2) FROM employee WHERE emp_id = 1;
  2. ABS(-2)|ABS(2)| -------|------| 2| 2|

2 和 -2 的绝对值都是 2。

取整函数

CEIL 和 CEILING 函数向上取整,FLOOR 函数向下取整,ROUND 函数执行四舍五入运算:

  1. SELECT CEIL(1.9), -- SQL Server 使用 CEILING(1.9) FLOOR(4.5), ROUND(9.456, 1) FROM employee WHERE emp_id = 1;
  2. CEIL(1.9)|FLOOR(4.5)|ROUND(9.456, 1)|
  3. ---------|----------|---------------|
  4. 2| 4| 9.5|

1.9 向上取整为 2,4.5 向下取整为 4,9.456 四舍五入到一位小数得到 9.5。
Oracle 只实现了 CEIL 函数,SQL Server 只实现了 CEILING 函数。

指数函数

EXP 函数计算自然常数 e 的 N 次方,POWER 函数计算指定底数的 N 次方:

  1. SELECT EXP(1), POWER(2, 4) FROM employee WHERE emp_id = 1;
  2. EXP(1) |POWER(2, 4)|
  3. -----------------|-----------|
  4. 2.718281828459045| 16|

自然常数 e 约等于 2.71828,2 的 4 次方等于 16。

对数函数

LN 函数计算以 e 为底的自然对数,LOG 函数计算指定底数的对数:

  1. -- OracleMySQL 以及 PostgreSQL 实现
  2. SELECT LOG(6, 36), LN(2.7182818285) FROM employee WHERE emp_id = 1;
  3. -- SQL Server 实现
  4. SELECT LOG(36, 6), LOG(2.7182818285) FROM employee WHERE emp_id = 1;

该查询的结果如下:

  1. LOG(6, 36)|LN(2.7182818285)|
  2. ----------|----------------|
  3. 2| 1|

SQL Server 中对数函数的实现有所不同,它使用 LOG(x) 计算 x 的自然对数 LN(x);并且使用 LOG(x, y) 计算以 y 为底的 x 的对数,其他数据库使用 LOG(y, x)。

平方根函数

SQRT 函数计算数据的平方根:

  1. SELECT SQRT(25) FROM employee WHERE emp_id = 1;
  2. SQRT(25)|
  3. --------|
  4. 5|

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 函数分别计算参数列表中的最大值和最小值:

  1. -- OracleMySQL 以及 PostgreSQL 实现
  2. SELECT GREATEST(1, 2, 3), LEAST(1, 2, 3) FROM employee WHERE emp_id = 1;
  3. GREATEST(1, 2, 3)|LEAST(1, 2, 3)|
  4. -----------------|--------------|
  5. 3| 1|

1、2、3 中最大的是 3,最小的是 1。SQL Server 目前没有提供这两个函数。

生成随机数

生成随机数的函数在各种数据库中的实现不同:

  1. -- MySQL SQL Server 实现
  2. SELECT RAND() FROM employee WHERE emp_id = 1;
  3. RAND() |
  4. ------------------|
  5. 0.8572325947296178|
  6. -- Oracle 实现
  7. SELECT DBMS_RANDOM.VALUE FROM employee WHERE emp_id = 1;
  8. VALUE |
  9. ----------------------------------------|
  10. 0.33095309998157211073097228949436162842|
  11. -- PostgreSQL 实现
  12. SELECT RANDOM() FROM employee WHERE emp_id = 1;
  13. random |
  14. ------------------|
  15. 0.7409744057804346|

随机数函数每次都会返回不同的结果,所以你的结果应该和上面的数据并不相同。
其他常见的数值函数还有三角函数,例如 sin(x)、cos(x) 等。它们都是一些通用的数学函数,需要时可以查看数据库相关的文档。

小结

掌握常见的 SQL 函数将会方便我们进行数据的处理和分析,避免重复实现已有的功能。本篇主要介绍了常见的数值函数,大多数函数都可以在不同的数据库之间通用,但是也存在一些数据库专有的函数实现。
思考题:如何实现查询语句,每次执行时从员工表中返回随机的 5 条不同的数据?