首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 數學函數完整參考手冊:從基礎運算到三角函數的實戰用法與陷阱避坑

     編輯:MySQL 資料庫相關知識

數值運算核心函數

1. 絕對值 ABS(x)


SELECT ABS(1), ABS(-1), ABS(0);
-- 1, 1, 0
  • 返回類型與參數相同
  • ABS(-9223372036854775808) 溢出返回負數(符號位無法翻轉),需注意邊界

2. 圓周率 PI()


SELECT PI();  -- 3.141592653589793
  • 返回 DOUBLE 精度常量
  • 三角函數參數均為**弧度**,配合 RADIANS() 轉換

3. 平方根 SQRT(x)


SELECT SQRT(49), SQRT(0), SQRT(-49);
-- 7, 0, NULL
  • 參數 < 0 返回 NULL(不報錯)
  • 精度為 DOUBLE

4. 取模 MOD(x, y) / x % y


SELECT MOD(31,8), MOD(21,-8), MOD(-7,2), MOD(-7,-2), MOD(45.5,6);
-- 7, 5, -1, -1, 3.5
  • 支持小數,返回精確餘數
  • 符號規則:結果符號與**被除數 (x) 相同**
  • MOD(x,0) 返回 NULL

5. 向上取整 CEIL(x) / CEILING(x)


SELECT CEIL(-3.35), CEIL(3.35), CEILING(-3.35);
-- -3, 4, -3
  • 返回 BIGINT(MySQL 8.0+)或 DECIMAL
  • CEIL 和 CEILING 完全等價

6. 向下取整 FLOOR(x)


SELECT FLOOR(-3.35), FLOOR(3.35);
-- -4, 3
  • 負數向「更負」方向取整(-3.35 → -4)
  • 常用於分頁計算:FLOOR((offset-1)/page_size)

7. 四捨五入 ROUND(x, d)


SELECT ROUND(-1.14), ROUND(-1.9), ROUND(1.14), ROUND(1.9);
-- -1, -2, 1, 2

SELECT ROUND(1.38,1), ROUND(1.38,0), ROUND(232.38,-1), ROUND(232.38,-2);
-- 1.4, 1, 230, 200
  • d > 0:保留小數點後 d 位
  • d = 0:四捨五入到整數
  • d < 0:從小數點向左 d 位四捨五入(十位、百位)
  • 銀行家舍入:MySQL 8.0.21+ 支持 ROUND(x, d, mode),mode=1 為銀行家舍入(偶數優先)

8. 截斷 TRUNCATE(x, d)


SELECT TRUNCATE(1.33,1), TRUNCATE(1.99,1), TRUNCATE(1.99,0), TRUNCATE(19.99,-1);
-- 1.3, 1.9, 1, 10
  • **不四捨五入**,直接截斷
  • d **必須提供**,無默認值
  • 財務計算首選,避免累積誤差

9. 符號 SIGN(x)


SELECT SIGN(-21), SIGN(-0), SIGN(0), SIGN(0.0), SIGN(21);
-- -1, 0, 0, 0, 1
  • 返回 -1、0、1 三值
  • 常用於條件表達式:CASE SIGN(x) WHEN 1 THEN '正' WHEN -1 THEN '負' ELSE '零' END

冪、指數、對數函數

10. 冪運算 POW(x, y) / POWER(x, y)


SELECT POW(2,2), POW(2,-2), POW(-2,2), POW(-2,-2);
-- 4, 0.25, 4, 0.25
  • 等價於 x ^ y(注意:MySQL 中 ^ 是位異或,非冪運算)
  • 返回 DOUBLE

11. 自然指數 EXP(x) = e^x


SELECT EXP(3), EXP(0), EXP(-3);
-- 20.0855, 1, 0.049787
  • EXP(LOG(x)) = x (x > 0)
  • 溢出閾值:EXP(709) ≈ 1e308,再大返回 NULL + 警告

12. 自然對數 LOG(x) / LN(x)


SELECT LOG(3), LOG(-3), LOG(0);
-- 1.0986, NULL, NULL
  • 參數 ≤ 0 返回 NULL
  • LOG(b, x) 以 b 為底對數(MySQL 8.0+)

13. 常用對數 LOG10(x)


SELECT LOG10(100), LOG10(-100), LOG10(0);
-- 2, NULL, NULL
  • 等價於 LOG(10, x)

角度弧度轉換

14. RADIANS(deg) 角度→弧度

15. DEGREES(rad) 弧度→角度


SELECT RADIANS(90), RADIANS(180), DEGREES(PI()), DEGREES(PI()/2);
-- 1.5708, 3.1416, 180, 90
  • 公式:弧度 = 角度 * PI() / 180
  • 所有三角函數參數**必須為弧度**

三角函數族

正弦/反正弦


SELECT SIN(PI()/2), ASIN(1), ASIN(2);
-- 1, 1.5708, NULL
  • SIN(x):x 為弧度,返回 [-1, 1]
  • ASIN(x):x 必須在 [-1, 1],否則 NULL

餘弦/反餘弦


SELECT COS(PI()), ACOS(-1), ACOS(2);
-- -1, 3.1416, NULL

正切/反正切


SELECT TAN(PI()/4), ATAN(1), ATAN2(1,1);
-- 1, 0.7854, 0.7854
  • ATAN2(y, x):返回向量 (x,y) 與 X 軸夾角,**支持象限判斷**,比 ATAN(y/x) 更健壯

餘切


SELECT COT(0.5), COT(0);
-- 1.8305, NULL (除零)
  • COT(x) = 1/TAN(x) = COS(x)/SIN(x)
  • x = k*PI() 時 SIN(x)=0,返回 NULL

隨機數函數

RAND() 與 RAND(seed)


-- 無種子:每次調用返回不同值
SELECT RAND(), RAND(), RAND();
-- 0.693, 0.515, 0.494

-- 有種子:同種子序列固定,可復現
SELECT RAND(10), RAND(10), RAND(2), RAND(-2);
-- 0.65705, 0.65705, 0.65559, 0.65485
  • 返回 [0, 1) 區間 DOUBLE
  • 種子作用域:會話級,同一連接內同種子產生相同序列
  • 常用場景:ORDER BY RAND() LIMIT 10 隨機抽樣(大表慎用,全表掃描)

實戰避坑指南

⚠️ 高頻陷阱

  • 整數除法截斷:SELECT 5/2 → 2.5 (MySQL 默認非整數除法);SELECT 5 DIV 2 → 2 (整數除法)
  • 精度陷阱:SELECT 0.1 + 0.2 = 0.3 → 0 (浮點誤差);用 ROUND(0.1+0.2, 1) = 0.3 或 DECIMAL 類型
  • MOD 負數行為:MySQL 遵循「結果符號同被除數」,不同於 Python (-7 % 2 = 1)
  • ROUND 四捨五入規則:.5 向遠離零方向(ROUND(1.5)=2, ROUND(-1.5)=-2),非銀行家舍入
  • 三角函數單位:永遠記住**弧度**!SIN(90) ≠ 1,SIN(RADIANS(90)) = 1
  • RAND() 性能:ORDER BY RAND() 會生成臨時表排序,**百萬級表極慢**;改用 WHERE RAND() < 0.01 伯努利採樣或應用層隨機 ID

綜合應用案例

案例 1:計算兩點經緯度距離


-- Haversine 公式
SET @lat1 = RADIANS(39.9042);  -- 北京
SET @lon1 = RADIANS(116.4074);
SET @lat2 = RADIANS(31.2304);  -- 上海
SET @lon2 = RADIANS(121.4737);

SELECT 6371 * 2 * ASIN(SQRT(
    POW(SIN((@lat2 - @lat1)/2), 2) +
    COS(@lat1) * COS(@lat2) * POW(SIN((@lon2 - @lon1)/2), 2)
)) AS distance_km;
-- 約 1084 km

案例 2:分頁隨機抽樣(避免 ORDER BY RAND)


-- 伯努利採樣:每行獨立以概率 p 選中
SELECT * FROM large_table 
WHERE RAND() < 0.001  -- 0.1% 採樣率
LIMIT 100;

-- 系統採樣:按主鍵區間跳躍
SELECT * FROM large_table 
WHERE id % 1000 = FLOOR(RAND() * 1000)
LIMIT 100;

案例 3:財務金額精確計算


-- 錯誤:浮點累積
SELECT SUM(price * quantity) FROM order_items;  -- 可能 100.0000000001

-- 正確:轉分計算或 DECIMAL
SELECT TRUNCATE(SUM(ROUND(price * 100) * quantity) / 100, 2) FROM order_items;
-- 或表結構定義:price DECIMAL(10,2)

總結

MySQL 數學函數涵蓋科學計算、財務核算、地理空間、隨機抽樣等全域場景。掌握核心在於:

  1. **類型與精度**:優先 DECIMAL 存儲金額,DOUBLE 科學計算
  2. **邊界行為**:NULL 传播、除零、溢出、定義域錯誤均返回 NULL+警告
  3. **單位一致**:三角函數嚴格弧度,角度必須轉換
  4. **性能意識**:RAND()、SQRT()、三角函數在大表 WHERE 條件中會導致全表掃描,應在應用層或子查詢預計算

善用 TRUNCATE 替代 ROUND 做財務截斷,用 ATAN2 替代 ATAN 做角度計算,用 POW 而非 ^ 做冪運算,這些細節決定計算的正確性與性能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved