SQL数值函数
# SQL数值函数
作者:哪吒
时间:2024年12月
# 概述
SQL数值函数用于对数值数据进行各种数学运算和处理。这些函数可以帮助我们进行计算、格式化数字、处理精度等操作。
# 基本数学函数
# ABS() - 绝对值
返回数值的绝对值。
SELECT ABS(-15) AS absolute_value; -- 结果: 15
SELECT ABS(25) AS absolute_value; -- 结果: 25
SELECT ABS(-3.14) AS absolute_value; -- 结果: 3.14
# ROUND() - 四舍五入
将数值四舍五入到指定的小数位数。
-- 基本用法
SELECT ROUND(3.14159) AS rounded; -- 结果: 3
SELECT ROUND(3.14159, 2) AS rounded; -- 结果: 3.14
SELECT ROUND(3.14159, 4) AS rounded; -- 结果: 3.1416
-- 负数小数位
SELECT ROUND(1234.5678, -1) AS rounded; -- 结果: 1230
SELECT ROUND(1234.5678, -2) AS rounded; -- 结果: 1200
# CEIL() / CEILING() - 向上取整
返回大于或等于指定数值的最小整数。
SELECT CEIL(3.14) AS ceiling_value; -- 结果: 4
SELECT CEIL(-3.14) AS ceiling_value; -- 结果: -3
SELECT CEILING(5.01) AS ceiling_value; -- 结果: 6
# FLOOR() - 向下取整
返回小于或等于指定数值的最大整数。
SELECT FLOOR(3.14) AS floor_value; -- 结果: 3
SELECT FLOOR(-3.14) AS floor_value; -- 结果: -4
SELECT FLOOR(5.99) AS floor_value; -- 结果: 5
# TRUNCATE() - 截断
截断数值到指定的小数位数(不进行四舍五入)。
SELECT TRUNCATE(3.14159, 2) AS truncated; -- 结果: 3.14
SELECT TRUNCATE(3.19999, 2) AS truncated; -- 结果: 3.19
SELECT TRUNCATE(1234.5678, -1) AS truncated; -- 结果: 1230
# 幂运算和根运算
# POWER() / POW() - 幂运算
计算数值的幂。
SELECT POWER(2, 3) AS power_result; -- 结果: 8 (2的3次方)
SELECT POW(5, 2) AS power_result; -- 结果: 25 (5的2次方)
SELECT POWER(10, -2) AS power_result; -- 结果: 0.01
# SQRT() - 平方根
计算数值的平方根。
SELECT SQRT(16) AS square_root; -- 结果: 4
SELECT SQRT(2) AS square_root; -- 结果: 1.4142135623731
SELECT SQRT(100) AS square_root; -- 结果: 10
# EXP() - 自然指数
计算e的指定次幂。
SELECT EXP(1) AS exp_result; -- 结果: 2.718281828459 (e)
SELECT EXP(0) AS exp_result; -- 结果: 1
SELECT EXP(2) AS exp_result; -- 结果: 7.3890560989307
# LOG() - 对数
计算自然对数或指定底数的对数。
-- 自然对数
SELECT LOG(2.718281828459) AS natural_log; -- 结果: 1
SELECT LN(10) AS natural_log; -- 结果: 2.302585092994
-- 指定底数的对数
SELECT LOG(10, 100) AS log_result; -- 结果: 2 (以10为底100的对数)
SELECT LOG(2, 8) AS log_result; -- 结果: 3 (以2为底8的对数)
# 三角函数
# SIN(), COS(), TAN() - 基本三角函数
-- 角度需要转换为弧度
SELECT SIN(PI()/2) AS sin_90; -- 结果: 1 (sin 90°)
SELECT COS(0) AS cos_0; -- 结果: 1 (cos 0°)
SELECT TAN(PI()/4) AS tan_45; -- 结果: 1 (tan 45°)
-- 角度转弧度: 角度 * PI() / 180
SELECT SIN(30 * PI() / 180) AS sin_30_degrees; -- 结果: 0.5
# ASIN(), ACOS(), ATAN() - 反三角函数
SELECT ASIN(0.5) AS arcsin; -- 结果: 0.5236 (30°的弧度值)
SELECT ACOS(0.5) AS arccos; -- 结果: 1.0472 (60°的弧度值)
SELECT ATAN(1) AS arctan; -- 结果: 0.7854 (45°的弧度值)
-- 弧度转角度: 弧度 * 180 / PI()
SELECT ASIN(0.5) * 180 / PI() AS arcsin_degrees; -- 结果: 30
# 特殊数值函数
# PI() - 圆周率
返回π的值。
SELECT PI() AS pi_value; -- 结果: 3.141592653590
# RAND() - 随机数
生成0到1之间的随机数。
SELECT RAND() AS random_number; -- 结果: 0.123456789 (随机)
SELECT RAND(123) AS seeded_random; -- 结果: 固定种子的随机数
SELECT FLOOR(RAND() * 100) AS random_int; -- 结果: 0-99的随机整数
# SIGN() - 符号函数
返回数值的符号(-1, 0, 1)。
SELECT SIGN(-15) AS sign_value; -- 结果: -1
SELECT SIGN(0) AS sign_value; -- 结果: 0
SELECT SIGN(25) AS sign_value; -- 结果: 1
# 数值格式化函数
# FORMAT() - 数值格式化
将数值格式化为指定格式的字符串。
SELECT FORMAT(1234.5678, 2) AS formatted; -- 结果: '1,234.57'
SELECT FORMAT(1234567.89, 0) AS formatted; -- 结果: '1,234,568'
SELECT FORMAT(123.456, 4) AS formatted; -- 结果: '123.4560'
# CONV() - 进制转换
在不同进制之间转换数值。
SELECT CONV('255', 10, 16) AS hex_value; -- 结果: 'FF' (十进制转十六进制)
SELECT CONV('FF', 16, 10) AS decimal_value; -- 结果: '255' (十六进制转十进制)
SELECT CONV('1010', 2, 10) AS binary_to_dec; -- 结果: '10' (二进制转十进制)
# 实战示例
# 示例1:计算商品价格统计
-- 创建测试数据
CREATE TABLE products (
id INT PRIMARY KEY,
name VARCHAR(100),
price DECIMAL(10,2),
discount_rate DECIMAL(3,2)
);
INSERT INTO products VALUES
(1, '笔记本电脑', 5999.99, 0.15),
(2, '手机', 2999.50, 0.10),
(3, '平板', 1899.00, 0.20);
-- 计算折后价格和统计信息
SELECT
name,
price AS original_price,
ROUND(price * (1 - discount_rate), 2) AS discounted_price,
ROUND(price * discount_rate, 2) AS discount_amount,
CEIL(price * (1 - discount_rate)) AS rounded_up_price,
FORMAT(price, 2) AS formatted_price
FROM products;
# 示例2:数学计算应用
-- 计算圆的面积和周长
SELECT
5 AS radius,
ROUND(PI() * POWER(5, 2), 2) AS area,
ROUND(2 * PI() * 5, 2) AS circumference;
-- 计算三角形边长(勾股定理)
SELECT
3 AS side_a,
4 AS side_b,
ROUND(SQRT(POWER(3, 2) + POWER(4, 2)), 2) AS hypotenuse;
# 示例3:随机数据生成
-- 生成随机测试数据
SELECT
FLOOR(RAND() * 1000) + 1 AS random_id,
ROUND(RAND() * 100, 2) AS random_score,
FLOOR(RAND() * 50) + 18 AS random_age,
CASE
WHEN RAND() > 0.5 THEN '男'
ELSE '女'
END AS random_gender;
# 性能优化建议
# 1. 避免在WHERE子句中使用函数
-- 不推荐:在WHERE中使用函数
SELECT * FROM orders WHERE ROUND(amount, 0) = 100;
-- 推荐:使用范围查询
SELECT * FROM orders WHERE amount >= 99.5 AND amount < 100.5;
# 2. 预计算常用值
-- 不推荐:每次都计算
SELECT *, price * 0.8 AS discounted_price FROM products;
-- 推荐:添加计算列或在应用层计算
ALTER TABLE products ADD COLUMN discounted_price DECIMAL(10,2)
GENERATED ALWAYS AS (price * 0.8) STORED;
# 3. 合理使用精度
-- 根据业务需求选择合适的精度
SELECT
ROUND(price, 2) AS price_display, -- 显示用,2位小数
TRUNCATE(price, 4) AS price_calc -- 计算用,4位小数
FROM products;
# 常见错误和解决方案
# 1. 除零错误
-- 错误:可能导致除零
SELECT 10 / 0; -- 错误
-- 正确:使用条件判断
SELECT
CASE
WHEN denominator = 0 THEN NULL
ELSE numerator / denominator
END AS safe_division
FROM calculations;
# 2. 精度丢失
-- 注意:浮点数精度问题
SELECT 0.1 + 0.2 = 0.3; -- 可能返回 false
-- 解决:使用DECIMAL类型或适当的精度比较
SELECT ABS((0.1 + 0.2) - 0.3) < 0.0001 AS is_equal;
# 3. 负数开方
-- 错误:负数开方
SELECT SQRT(-4); -- 错误
-- 正确:先检查符号
SELECT
CASE
WHEN value >= 0 THEN SQRT(value)
ELSE NULL
END AS safe_sqrt
FROM numbers;
# 最佳实践
- 选择合适的数据类型:根据精度要求选择DECIMAL、FLOAT或DOUBLE
- 避免过度精度:不要使用超过业务需求的精度
- 处理边界情况:考虑NULL值、零值、负值等特殊情况
- 性能考虑:在大数据量时避免复杂的数学运算
- 文档化计算逻辑:为复杂的数学计算添加注释
# 总结
SQL数值函数提供了强大的数学计算能力,合理使用这些函数可以:
- 简化复杂的数学运算
- 提高数据处理效率
- 确保计算结果的准确性
- 满足各种业务场景的需求
在使用时要注意精度、性能和边界情况的处理,选择最适合业务需求的函数和方法。