概要

MySQLでは、豊富な数値関数が提供されており、算術演算、丸め処理、三角関数、対数関数、ビット演算等を実行できる。
これらの関数は、SELECT文、UPDATE文、WHERE句等で使用でき、データ分析や計算処理において重要な役割を果たす。

数値関数は、整数型 (INT, BIGINT)、固定小数点型 (DECIMAL)、浮動小数点型 (FLOAT, DOUBLE) の各データ型に対応している。
ただし、浮動小数点型では丸め誤差が発生するため、金額計算等の精度が重要な処理ではDECIMAL型の使用を推奨する。

MySQL 5.7とMySQL 8.0では、数値関数の動作に大きな差異はないが、一部の関数で精度や型推論の挙動が改善されている。

集約関数 (SUM, AVG, COUNT, MIN, MAX等) については、MySQL - 集約関数 を参照すること。

数値関数を WHERE 句で使用すると、インデックスが使用されない場合が多い。
パフォーマンスを考慮する場合は、関数を使用しないクエリ設計を検討する必要がある。


算術演算子

MySQLでは、基本的な算術演算子が提供されている。
これらの演算子は、数値型カラムの計算やSELECT文での即値計算に使用できる。

基本算術演算子

MySQLで使用可能な基本算術演算子を以下に示す。

基本算術演算子
演算子 説明 使用例 結果
+ 加算 SELECT 10 + 5 15
- 減算 SELECT 10 - 5 5
* 乗算 SELECT 10 * 5 50
/ 除算 SELECT 10 / 5 2.0000
DIV 整数除算 SELECT 10 DIV 3 3
% 剰余 (MOD) SELECT 10 % 3 1
MOD 剰余 (関数形式) SELECT MOD(10, 3) 1


基本的な使用例を以下に示す。

算術演算子は、数値型カラム同士の計算だけでなく、即値との計算にも使用できる。

 SELECT 10 + 5;
 -- 結果: 15
 
 SELECT 10 - 5;
 -- 結果: 5
 
 SELECT 10 * 5;
 -- 結果: 50
 
 SELECT 10 / 5;
 -- 結果: 2.0000
 
 SELECT 100 + 200 AS sum, 100 - 50 AS diff;
 -- 結果: sum=300, diff=50
 
 SELECT price * quantity AS total FROM order_items;


除算の動作

除算演算子 (/) と整数除算演算子 (DIV) の動作の違いを以下に示す。

 SELECT 3 / 2;
 -- 結果: 1.5000 (DECIMAL型として返される)
 
 SELECT 3 DIV 2;
 -- 結果: 1 (整数部分のみを返す)
 
 SELECT 10 / 3;
 -- 結果: 3.3333
 
 SELECT 10 DIV 3;
 -- 結果: 3
 
 SELECT 7.5 / 2;
 -- 結果: 3.75000
 
 SELECT 7.5 DIV 2;
 -- 結果: 3 (整数部分のみ)


除算演算子 (/) は、DECIMAL型の結果を返す。
整数除算演算子 (DIV) は、商の整数部分のみを返す。

ゼロ除算の動作を以下に示す。

ゼロ除算は、エラーではなくNULLを返す。

 SELECT 10 / 0;
 -- 結果: NULL (ゼロ除算はNULLを返す)
 
 SELECT 10 DIV 0;
 -- 結果: NULL
 
 SELECT 10 / NULL;
 -- 結果: NULL


MOD (剰余) 演算

剰余演算は、割り算の余りを返す。
% 演算子 と MOD 関数は同一の動作をする。

 SELECT 7 MOD 3;
 -- 結果: 1
 
 SELECT 7 % 3;
 -- 結果: 1
 
 SELECT MOD(7, 3);
 -- 結果: 1 (関数形式)
 
 SELECT 10 MOD 5;
 -- 結果: 0 (割り切れる場合は0)
 
 SELECT 10 MOD 3;
 -- 結果: 1
 
 SELECT -10 MOD 3;
 -- 結果: -1 (負数の場合は符号が保持される)
 
 SELECT 10 MOD -3;
 -- 結果: 1
 
 SELECT -10 MOD -3;
 -- 結果: -1


剰余演算の結果の符号は、被除数の符号に従う。

剰余演算の実用例を以下に示す。

 -- 偶数・奇数の判定
 SELECT id, id % 2 AS is_odd FROM users;
 -- is_odd=0: 偶数、is_odd=1: 奇数
 
 -- 3件ごとにグループ分け
 SELECT id, id % 3 AS group_no FROM items;
 
 -- 曜日計算 (0=日曜, 6=土曜)
 SELECT DAYOFWEEK(order_date) % 7 AS weekday FROM orders;


演算精度と型の規則

MySQLの算術演算では、オペランドのデータ型に応じて結果の型が決定される。

型推論の規則を以下に示す。

算術演算の型推論規則
オペランド 結果型 説明
整数 + 整数 BIGINT 64ビット整数精度
DECIMAL + 整数 DECIMAL 固定小数点精度を保持
DECIMAL + DECIMAL DECIMAL より高い精度を採用
FLOAT/DOUBLE + 任意 DOUBLE 浮動小数点精度
整数 / 整数 DECIMAL 除算結果は小数を含む可能性


型推論の例を以下に示す。

 SELECT 10 + 20;
 -- 結果型: BIGINT
 
 SELECT 10.5 + 20;
 -- 結果型: DECIMAL
 
 SELECT 10.5 + 20.3;
 -- 結果型: DECIMAL
 
 SELECT 10.5E0 + 20;
 -- 結果型: DOUBLE (科学記法を使用した場合は浮動小数点)
 
 SELECT 3 / 2;
 -- 結果: 1.5000 (DECIMAL型)
 
 SELECT CAST(3 AS DECIMAL) / CAST(2 AS DECIMAL);
 -- 結果: 1.5000


整数オーバーフローの動作を以下に示す。

オーバーフロー動作は、sql_mode 設定により変化する。
デフォルトでは、オーバーフロー時にエラーが発生する。

 -- BIGINT範囲: -9223372036854775808 ~ 9223372036854775807
 
 SELECT 9223372036854775807 + 1;
 -- ERROR: BIGINT value is out of range (sql_modeによる)
 
 -- オーバーフロー許容モード (NO_UNSIGNED_SUBTRACTION無効)
 SET sql_mode = '';
 SELECT 9223372036854775807 + 1;
 -- 結果: 9223372036854775808 (BIGINT UNSIGNED範囲に昇格)



丸め関数

丸め関数は、数値を指定された精度に丸める処理を実行する。
MySQLでは、ROUND, TRUNCATE, CEIL, FLOOR 等の丸め関数が提供されている。

ROUND

ROUND 関数は、数値を指定された桁数に丸める。

基本構文を以下に示す。

 ROUND(x)
 ROUND(x, d)


引数の意味
引数 説明
第1引数 対象数値
第2引数 小数点以下の桁数 (省略時は0)。負の値を指定すると小数点より左側を丸める


丸め方式は、数値型により異なる。

  • 正確値型 (DECIMAL)
    round half away from zero (四捨五入)
  • 近似値型 (FLOAT, DOUBLE)
    実装依存 (銀行家の丸め/偶数丸めになる場合がある)


使用例を以下に示す。

 SELECT ROUND(2.5);
 -- 結果: 3 (正確値型として四捨五入)
 
 SELECT ROUND(-2.5);
 -- 結果: -3
 
 SELECT ROUND(2.55, 1);
 -- 結果: 2.6 (小数第2位を四捨五入)
 
 SELECT ROUND(2.54, 1);
 -- 結果: 2.5
 
 SELECT ROUND(123.456, 2);
 -- 結果: 123.46
 
 SELECT ROUND(123.456, 0);
 -- 結果: 123
 
 SELECT ROUND(123.456, -1);
 -- 結果: 120 (小数点より左側を丸める)
 
 SELECT ROUND(123.456, -2);
 -- 結果: 100
 
 SELECT ROUND(2.55E0, 1);
 -- 結果: 2.5 (近似値型で偶数丸めになる可能性)


負の桁数指定により、整数部分の丸めが可能である。

浮動小数点型と正確値型の丸め動作の違いを以下に示す。

金額計算等の精度が重要な処理では、DECIMAL型の使用を推奨する。

 -- 正確値型 (DECIMAL)
 SELECT ROUND(2.5);
 -- 結果: 3
 
 SELECT ROUND(3.5);
 -- 結果: 4
 
 -- 近似値型 (DOUBLE)
 SELECT ROUND(2.5E0);
 -- 結果: 2 (偶数丸めの可能性)
 
 SELECT ROUND(3.5E0);
 -- 結果: 4


TRUNCATE

TRUNCATE 関数は、小数部を切り捨てる。(0方向に切り捨て)

基本構文を以下に示す。

 TRUNCATE(x, d)


引数の意味
引数 説明
第1引数 対象数値
第2引数 小数点以下の桁数。負の値を指定すると小数点より左側を0にする


使用例を以下に示す。

 SELECT TRUNCATE(1.999, 1);
 -- 結果: 1.9 (小数第2位以降を切り捨て)
 
 SELECT TRUNCATE(1.999, 0);
 -- 結果: 1 (小数部を切り捨て)
 
 SELECT TRUNCATE(1.999, 2);
 -- 結果: 1.99
 
 SELECT TRUNCATE(-1.999, 1);
 -- 結果: -1.9 (0方向に切り捨て)
 
 SELECT TRUNCATE(122, -2);
 -- 結果: 100 (小数点より左側を0にする)
 
 SELECT TRUNCATE(123.456, -1);
 -- 結果: 120
 
 SELECT TRUNCATE(123.456, -2);
 -- 結果: 100


TRUNCATE 関数は、四捨五入を行わず、単純に切り捨てる。

ROUND 関数と TRUNCATE 関数の違いを以下に示す。

 SELECT ROUND(1.999, 1);
 -- 結果: 2.0 (四捨五入)
 
 SELECT TRUNCATE(1.999, 1);
 -- 結果: 1.9 (切り捨て)
 
 SELECT ROUND(1.555, 2);
 -- 結果: 1.56
 
 SELECT TRUNCATE(1.555, 2);
 -- 結果: 1.55


CEIL / CEILING

CEIL 関数 および CEILING 関数は、x以上の最小の整数を返す。
これらは同一の関数である。

基本構文を以下に示す。

 CEIL(x)
 CEILING(x)


使用例を以下に示す。

CEIL 関数は、切り上げ処理に相当する。
ただし、負数では動作が異なるため注意が必要である。

 SELECT CEIL(1.23);
 -- 結果: 2
 
 SELECT CEILING(1.23);
 -- 結果: 2
 
 SELECT CEIL(-1.23);
 -- 結果: -1 (-1.23以上の最小の整数は-1)
 
 SELECT CEIL(5);
 -- 結果: 5 (整数の場合はそのまま)
 
 SELECT CEIL(1.01);
 -- 結果: 2
 
 SELECT CEIL(-1.01);
 -- 結果: -1


FLOOR

FLOOR 関数は、x以下の最大の整数を返す。

基本構文を以下に示す。

 FLOOR(x)


使用例を以下に示す。

FLOOR 関数は、切り捨て処理に相当する。
ただし、負数では TRUNCATE 関数と動作が異なる。

 SELECT FLOOR(1.23);
 -- 結果: 1
 
 SELECT FLOOR(-1.23);
 -- 結果: -2 (-1.23以下の最大の整数は-2)
 
 SELECT FLOOR(5);
 -- 結果: 5
 
 SELECT FLOOR(1.99);
 -- 結果: 1
 
 SELECT FLOOR(-1.01);
 -- 結果: -2


FLOOR 関数 と TRUNCATE 関数の違いを以下に示す。

FLOOR 関数は負の無限大方向に、TRUNCATE 関数は0方向に切り捨てる。

 SELECT FLOOR(1.99);
 -- 結果: 1
 
 SELECT TRUNCATE(1.99, 0);
 -- 結果: 1
 
 SELECT FLOOR(-1.99);
 -- 結果: -2 (負の無限大方向に切り捨て)
 
 SELECT TRUNCATE(-1.99, 0);
 -- 結果: -1 (0方向に切り捨て)



絶対値・符号関数

ABS

ABS 関数は、絶対値を返す。

基本構文を以下に示す。

 ABS(x)


使用例を以下に示す。

 SELECT ABS(-32);
 -- 結果: 32
 
 SELECT ABS(32);
 -- 結果: 32
 
 SELECT ABS(-123.45);
 -- 結果: 123.45
 
 SELECT ABS(0);
 -- 結果: 0
 
 SELECT ABS(NULL);
 -- 結果: NULL


ABS 関数の使用例を以下に示す。

 -- 残高の差分の絶対値を計算
 SELECT account_id, ABS(balance - target_balance) AS diff FROM accounts;
 
 -- 絶対値で並べ替え
 SELECT value FROM measurements ORDER BY ABS(value);


SIGN

SIGN 関数は、数値の符号を返す。

基本構文を以下に示す。

 SIGN(x)


戻り値を以下に示す。

SIGN 関数の戻り値
引数 戻り値
負数 -1
0 0
正数 1


使用例を以下に示す。

 SELECT SIGN(-32);
 -- 結果: -1
 
 SELECT SIGN(0);
 -- 結果: 0
 
 SELECT SIGN(32);
 -- 結果: 1
 
 SELECT SIGN(-123.45);
 -- 結果: -1
 
 SELECT SIGN(123.45);
 -- 結果: 1
 
 SELECT SIGN(NULL);
 -- 結果: NULL


SIGN 関数の例を以下に示す。

 -- 入出金の種別を判定
 SELECT transaction_id, amount,
        CASE SIGN(amount)
           WHEN -1 THEN '出金'
           WHEN 0 THEN '変動なし'
           WHEN 1 THEN '入金'
        END AS type
 FROM transactions;
 
 -- プラスの値のみを集計
 SELECT SUM(amount * (SIGN(amount) + 1) / 2) AS positive_sum FROM data;



累乗・平方根関数

POWER / POW

POWER 関数 および POW 関数は、xのy乗を返す。
これらは同一の関数である。

基本構文を以下に示す。

 POWER(x, y)
 POW(x, y)


戻り値はDOUBLE型である。

使用例を以下に示す。

 SELECT POW(2, 3);
 -- 結果: 8 (2の3乗)
 
 SELECT POWER(2, 3);
 -- 結果: 8
 
 SELECT POW(2, -2);
 -- 結果: 0.25 (2の-2乗 = 1/4)
 
 SELECT POW(10, 2);
 -- 結果: 100
 
 SELECT POW(2, 0);
 -- 結果: 1 (任意の数の0乗は1)
 
 SELECT POW(2, 0.5);
 -- 結果: 1.4142135623730951 (2の平方根)
 
 SELECT POW(4, 0.5);
 -- 結果: 2


負の指数を指定することで、逆数の計算が可能である。

実用例を以下に示す。

 -- 複利計算 (元金 * (1 + 利率) ^ 年数)
 SELECT principal * POW(1 + interest_rate, years) AS future_value
 FROM investments;
 
 -- 2のn乗でビット計算
 SELECT POW(2, bit_position) AS bit_value;


SQRT

SQRT 関数は、非負の平方根を返す。

基本構文を以下に示す。

 SQRT(x)


負の値を指定した場合はNULLを返す。

使用例を以下に示す。

 SELECT SQRT(4);
 -- 結果: 2
 
 SELECT SQRT(20);
 -- 結果: 4.47213595499958
 
 SELECT SQRT(2);
 -- 結果: 1.4142135623730951
 
 SELECT SQRT(0);
 -- 結果: 0
 
 SELECT SQRT(-16);
 -- 結果: NULL (負数の平方根はNULL)
 
 SELECT SQRT(NULL);
 -- 結果: NULL


実用例を以下に示す。

 -- 2点間の距離を計算 (ピタゴラスの定理)
 SELECT SQRT(POW(x2 - x1, 2) + POW(y2 - y1, 2)) AS distance
 FROM points;
 
 -- 標準偏差の計算
 SELECT SQRT(AVG(POW(value - avg_value, 2))) AS std_dev FROM data;


EXP

EXP 関数は、eのx乗を返す。
eは自然対数の底 (2.71828...) である。

基本構文を以下に示す。

 EXP(x)


使用例を以下に示す。

 SELECT EXP(2);
 -- 結果: 7.3890560989306495 (e^2)
 
 SELECT EXP(-2);
 -- 結果: 0.1353352832366127 (e^-2)
 
 SELECT EXP(0);
 -- 結果: 1 (e^0)
 
 SELECT EXP(1);
 -- 結果: 2.718281828459045 (eの値)
 
 SELECT EXP(NULL);
 -- 結果: NULL


EXP 関数は、自然対数関数 LN の逆関数である。

 SELECT EXP(LN(10));
 -- 結果: 10
 
 SELECT LN(EXP(5));
 -- 結果: 5



対数関数

対数関数は、指数の逆演算を実行する。
MySQLでは、自然対数、常用対数、任意の底の対数を計算できる。

LN / LOG

LN 関数は、自然対数 (底e) を返す。
LOG 関数は、引数が1つの場合は自然対数を返し、引数が2つの場合は任意の底の対数を返す。

基本構文を以下に示す。

 LN(x)
 LOG(x)
 LOG(b, x)


引数の意味
関数形式 説明
LN(x) xの自然対数 (底e)
LOG(x) xの自然対数 (LN(x)と同じ)
LOG(b, x) 底bに対するxの対数


x0 の場合は、NULL を返す。

使用例を以下に示す。

 SELECT LN(2);
 -- 結果: 0.6931471805599453 (log_e(2))
 
 SELECT LOG(2);
 -- 結果: 0.6931471805599453 (LN(2)と同じ)
 
 SELECT LN(EXP(1));
 -- 結果: 1 (eの自然対数は1)
 
 SELECT LOG(10, 100);
 -- 結果: 2 (log_10(100) = 2)
 
 SELECT LOG(2, 256);
 -- 結果: 8 (log_2(256) = 8, 2^8 = 256)
 
 SELECT LOG(10, 1000);
 -- 結果: 3
 
 SELECT LN(1);
 -- 結果: 0 (log_e(1) = 0)
 
 SELECT LN(0);
 -- 結果: NULL (0以下はNULL)
 
 SELECT LN(-10);
 -- 結果: NULL


任意の底の対数を計算する例を以下に示す。

 SELECT LOG(2, 1024);
 -- 結果: 10 (2^10 = 1024)
 
 SELECT LOG(3, 81);
 -- 結果: 4 (3^4 = 81)
 
 SELECT LOG(5, 625);
 -- 結果: 4 (5^4 = 625)


LOG2

LOG2 関数は、底2の対数を返す。

基本構文を以下に示す。

 LOG2(x)


使用例を以下に示す。

 SELECT LOG2(65536);
 -- 結果: 16 (2^16 = 65536)
 
 SELECT LOG2(256);
 -- 結果: 8
 
 SELECT LOG2(2);
 -- 結果: 1
 
 SELECT LOG2(1);
 -- 結果: 0
 
 SELECT LOG2(1024);
 -- 結果: 10


LOG2 関数は、ビット幅の計算に有用である。

 -- 値を表現するために必要なビット数
 SELECT CEIL(LOG2(max_value + 1)) AS required_bits;


LOG10

LOG10 関数は、常用対数 (底が10) を返す。

基本構文を以下に示す。

 LOG10(x)


使用例を以下に示す。

 SELECT LOG10(100);
 -- 結果: 2 (10^2 = 100)
 
 SELECT LOG10(1000);
 -- 結果: 3
 
 SELECT LOG10(10);
 -- 結果: 1
 
 SELECT LOG10(1);
 -- 結果: 0
 
 SELECT LOG10(1000000);
 -- 結果: 6


LOG10 関数は、桁数の計算に有用である。

 -- 正の整数の桁数を計算
 SELECT FLOOR(LOG10(value)) + 1 AS digit_count FROM numbers;



三角関数

MySQLでは、基本三角関数、逆三角関数、角度変換関数が提供されている。
全ての三角関数は、引数をラジアンで受け取る。

基本三角関数

下表に、基本的な三角関数を示す。

基本三角関数
関数 説明 使用例 結果
SIN(x) 正弦 (サイン) SELECT SIN(PI()/2) 1
COS(x) 余弦 (コサイン) SELECT COS(PI()) -1
TAN(x) 正接 (タンジェント) SELECT TAN(PI()/4) 1
COT(x) 余接 (コタンジェント) SELECT COT(PI()/4) 1


使用例を以下に示す。

 SELECT SIN(PI()/2);
 -- 結果: 1 (90度のサイン)
 
 SELECT COS(PI());
 -- 結果: -1 (180度のコサイン)
 
 SELECT TAN(PI()/4);
 -- 結果: 0.9999999999999999 (約1、45度のタンジェント)
 
 SELECT COT(PI()/4);
 -- 結果: 1.0000000000000002 (約1、45度のコタンジェント)
 
 SELECT SIN(0);
 -- 結果: 0
 
 SELECT COS(0);
 -- 結果: 1


逆三角関数

逆三角関数は、三角関数の逆演算を実行する。
戻り値はラジアンである。

逆三角関数
関数 説明 定義域 値域
ASIN(x) 逆正弦 (アークサイン) -1 ≤ x ≤ 1 -π/2 ~ π/2
ACOS(x) 逆余弦 (アークコサイン) -1 ≤ x ≤ 1 0 ~ π
ATAN(x) 逆正接 (アークタンジェント) 全ての実数 -π/2 ~ π/2
ATAN2(y, x) 2引数逆正接 全ての実数 -π ~ π


使用例を以下に示す。

 SELECT ASIN(1);
 -- 結果: 1.5707963267948966 (π/2、90度)
 
 SELECT ACOS(-1);
 -- 結果: 3.141592653589793 (π、180度)
 
 SELECT ATAN(1);
 -- 結果: 0.7853981633974483 (π/4、45度)
 
 SELECT ATAN2(1, 1);
 -- 結果: 0.7853981633974483 (π/4、45度)
 
 SELECT ASIN(2);
 -- 結果: NULL (定義域外)
 
 SELECT ASIN(-1);
 -- 結果: -1.5707963267948966 (-π/2、-90度)


ATAN2 関数は、座標 (x, y) の角度を計算する場合に有用である。

 SELECT ATAN2(1, 0);
 -- 結果: 1.5707963267948966 (π/2、90度、y軸正方向)
 
 SELECT ATAN2(0, 1);
 -- 結果: 0 (x軸正方向)
 
 SELECT ATAN2(-1, 0);
 -- 結果: -1.5707963267948966 (-π/2、-90度、y軸負方向)
 
 SELECT ATAN2(0, -1);
 -- 結果: 3.141592653589793 (π、180度、x軸負方向)


角度変換

角度変換関数により、ラジアンと度の相互変換が可能である。

角度変換関数
関数 説明 使用例 結果
DEGREES(x) ラジアン → 度 SELECT DEGREES(PI()) 180
RADIANS(x) 度 → ラジアン SELECT RADIANS(180) 3.141592653589793


使用例を以下に示す。

 SELECT DEGREES(PI());
 -- 結果: 180
 
 SELECT DEGREES(PI()/2);
 -- 結果: 90
 
 SELECT RADIANS(180);
 -- 結果: 3.141592653589793 (π)
 
 SELECT RADIANS(90);
 -- 結果: 1.5707963267948966 (π/2)
 
 SELECT RADIANS(360);
 -- 結果: 6.283185307179586 (2π)


度単位での三角関数計算例を以下に示す。

 SELECT SIN(RADIANS(30));
 -- 結果: 0.49999999999999994 (約0.5、30度のサイン)
 
 SELECT COS(RADIANS(60));
 -- 結果: 0.5000000000000001 (約0.5、60度のコサイン)
 
 SELECT DEGREES(ASIN(0.5));
 -- 結果: 30.000000000000004 (約30度)


PI

PI 関数は、円周率πの値を返す。

基本構文を以下に示す。

 PI()


使用例を以下に示す。

 SELECT PI();
 -- 結果: 3.141593 (表示精度は倍精度)
 
 SELECT PI() * 2;
 -- 結果: 6.283185307179586 (2π)
 
 SELECT PI() / 2;
 -- 結果: 1.5707963267948966 (π/2)
 
 -- 円の面積計算 (πr^2)
 SELECT PI() * POW(radius, 2) AS area FROM circles;
 
 -- 円周計算 (2πr)
 SELECT 2 * PI() * radius AS circumference FROM circles;



ランダム関数

MySQLでは、乱数生成関数が提供されている。

RAND

RAND 関数は、0以上1未満の乱数を返す。
戻り値の型は、DOUBLE である。

基本構文を以下に示す。

 RAND()
 RAND(seed)


引数の意味
形式 説明
RAND() ランダムな乱数を生成
RAND(seed) シード値を指定して再現可能な乱数列を生成


使用例を以下に示す。

 SELECT RAND();
 -- 結果: 0.6912345678901234 (実行ごとに異なる)
 
 SELECT RAND();
 -- 結果: 0.1234567890123456 (毎回異なる値)
 
 SELECT RAND(100);
 -- 結果: 0.9546361446761204 (シード100の場合は常に同じ値)
 
 SELECT RAND(100);
 -- 結果: 0.9546361446761204 (シードが同じなら同じ値)
 
 SELECT RAND(200);
 -- 結果: 0.44880484265643147 (異なるシード)


シード値を指定することで、再現可能な乱数列を生成できる。
これは、テストデータ生成時に有用である。

整数範囲の乱数を生成する例を以下に示す。

 -- 1~6のランダム整数 (サイコロ)
 SELECT FLOOR(RAND() * 6) + 1;
 
 -- 0~99のランダム整数
 SELECT FLOOR(RAND() * 100);
 
 -- min~maxのランダム整数
 SELECT FLOOR(RAND() * (max - min + 1)) + min;
 
 -- 10~20のランダム整数
 SELECT FLOOR(RAND() * 11) + 10;


ランダムにレコードを取得する例を以下に示す。

 -- ランダムに1行取得
 SELECT * FROM users ORDER BY RAND() LIMIT 1;
 
 -- ランダムに10行取得
 SELECT * FROM articles ORDER BY RAND() LIMIT 10;
 
 -- ランダムにソート
 SELECT id, name FROM products ORDER BY RAND();


※注意

  • ORDER BY RAND() は、全行に対して乱数を生成してソートするため、大量データでは非常に遅い。
    代替手法として、ランダムなIDを生成してWHERE句で絞り込む方法が推奨される。
  • 行ごとに RAND() の値は異なる。
    複数カラムで同一の乱数を使用する場合は、ユーザ変数を使用する。


大量データでのランダム抽出の代替手法を以下に示す。

 -- 代替手法1: ランダムなIDを生成
 SELECT * FROM users
 WHERE id >= (SELECT FLOOR(RAND() * (SELECT MAX(id) FROM users)))
 LIMIT 1;
 
 -- 代替手法2: サブクエリで最大ID取得
 SELECT * FROM users
 WHERE id >= FLOOR(1 + RAND() * (SELECT MAX(id) FROM users))
 LIMIT 1;



ビット演算

MySQLでは、整数値に対するビット演算が可能である。
MySQL 8.0以降では、64ビット整数 (BIGINT)バイナリ文字列 の両方に対応している。

ビット演算子

ビット演算子を以下に示す。

ビット演算子
演算子 説明 使用例 結果
& ビットAND SELECT 29 & 15 13
| ビットOR SELECT 29 | 15 31
^ ビットXOR (排他的論理和) SELECT 29 ^ 15 18
~ ビットNOT (反転) SELECT ~0 18446744073709551615
<< 左シフト SELECT 1 << 4 16
>> 右シフト SELECT 16 >> 2 4


下表に、戻り値を示す。

BIT_NOT 関数の戻り値の型
引数の型 戻り値の型
整数の場合 BIGINT UNSIGNED (64ビット符号なし整数)
バイナリ文字列の場合 同じ長さのバイナリ文字列


使用例を以下に示す。

 SELECT 29 & 15;
 -- 結果: 13 (11101 & 01111 = 01101)
 
 SELECT 29 | 15;
 -- 結果: 31 (11101 | 01111 = 11111)
 
 SELECT 29 ^ 15;
 -- 結果: 18 (11101 ^ 01111 = 10010)
 
 SELECT ~0;
 -- 結果: 18446744073709551615 (64ビット全て1)
 
 SELECT 1 << 4;
 -- 結果: 16 (1を4ビット左シフト = 10000)
 
 SELECT 16 >> 2;
 -- 結果: 4 (16を2ビット右シフト = 100)
 
 SELECT 8 >> 1;
 -- 結果: 4
 
 SELECT 8 << 1;
 -- 結果: 16


ビット演算の詳細な例を以下に示す。

 -- 特定ビットのチェック
 SELECT 29 & 1;
 -- 結果: 1 (最下位ビットが1)
 
 SELECT 28 & 1;
 -- 結果: 0 (最下位ビットが0、偶数判定)
 
 -- 特定ビットのセット
 SELECT 8 | 4;
 -- 結果: 12 (1000 | 0100 = 1100)
 
 -- 特定ビットのクリア
 SELECT 15 & ~4;
 -- 結果: 11 (1111 & 1011 = 1011)
 
 -- ビット反転
 SELECT ~15 & 0xFF;
 -- 結果: 240 (下位8ビット内で反転)


BIT_COUNT

BIT_COUNT 関数は、セットされたビット (1のビット) の数を返す。

基本構文を以下に示す。

 BIT_COUNT(n)


使用例を以下に示す。

 SELECT BIT_COUNT(29);
 -- 結果: 4 (11101 → 4個の1)
 
 SELECT BIT_COUNT(0);
 -- 結果: 0
 
 SELECT BIT_COUNT(255);
 -- 結果: 8 (11111111 → 8個の1)
 
 SELECT BIT_COUNT(7);
 -- 結果: 3 (111 → 3個の1)
 
 SELECT BIT_COUNT(8);
 -- 結果: 1 (1000 → 1個の1)


ビット演算の応用例

フラグ管理
 -- 権限フラグの定義
 -- 読み取り: 1 (001)
 -- 書き込み: 2 (010)
 -- 削除: 4 (100)
 
 -- 権限チェック
 SELECT permission & 4 AS can_read FROM users;
 -- 結果: 4 (権限あり) または 0 (権限なし)
 
 -- 読み取り権限の有無
 SELECT (permission & 1) > 0 AS has_read_permission FROM users;
 
 -- 権限の追加 (読み取り権限を追加)
 UPDATE users SET permission = permission | 1 WHERE user_id = 123;
 
 -- 権限の除去 (削除権限を除去)
 UPDATE users SET permission = permission & ~4 WHERE user_id = 123;
 
 -- 複数権限のセット (読み取り + 書き込み = 3)
 UPDATE users SET permission = 3 WHERE user_id = 123;
 
 -- 全ての権限を持つユーザ検索
 SELECT * FROM users WHERE (permission & 7) = 7;


IPアドレスのネットワークアドレス計算
 -- IPアドレス 192.168.1.100 (整数表現: 3232235876)
 -- サブネットマスク 255.255.255.0 (整数表現: 4294967040)
 
 -- ネットワークアドレス計算
 SELECT INET_NTOA(INET_ATON('192.168.1.100') & INET_ATON('255.255.255.0'));
 -- 結果: '192.168.1.0'
 
 -- ブロードキャストアドレス計算
 SELECT INET_NTOA(INET_ATON('192.168.1.100') | ~INET_ATON('255.255.255.0'));
 -- 結果: '192.168.1.255'


2の累乗判定
 -- 2の累乗はビットが1つだけセットされている
 SELECT n, (n & (n - 1)) = 0 AS is_power_of_2
 FROM numbers;
 
 -- 例: 8 & 7 = 1000 & 0111 = 0 (2の累乗)
 -- 例: 10 & 9 = 1010 & 1001 = 1000 (2の累乗ではない)



変換・フォーマット関数

数値を異なる形式に変換・フォーマットする関数を以下に示す。

FORMAT

FORMAT 関数は、数値を千の位区切りでフォーマットする。
戻り値は文字列である。

基本構文を以下に示す。

 FORMAT(x, d)
 FORMAT(x, d, locale)


引数の意味
引数 説明
第1引数 対象数値
第2引数 小数点以下の桁数
第3引数 ロケール (省略時は en_US)


使用例を以下に示す。

 SELECT FORMAT(12332.123456, 4);
 -- 結果: '12,332.1235' (小数第5位を四捨五入)
 
 SELECT FORMAT(12332.1, 4);
 -- 結果: '12,332.1000' (小数点以下を0でパディング)
 
 SELECT FORMAT(12332.2, 0);
 -- 結果: '12,332' (整数部のみ)
 
 SELECT FORMAT(1234567.89, 2);
 -- 結果: '1,234,567.89'
 
 SELECT FORMAT(1234567.89, 2, 'de_DE');
 -- 結果: '1.234.567,89' (ドイツ語ロケール)
 
 SELECT FORMAT(12332.2, 2, 'de_DE');
 -- 結果: '12.332,20'


ロケールによる表示形式の違いを以下に示す。

ロケールによる表示形式
ロケール 千の位区切り 小数点記号
en_US カンマ (,) ピリオド (.) 1,234.56
de_DE ピリオド (.) カンマ (,) 1.234,56
fr_FR スペース カンマ (,) 1 234,56


CONV

CONV 関数は、異なる基数 (進数) 間で数値を変換する。
2進数から36進数までの変換が可能である。

基本構文を以下に示す。

 CONV(n, from_base, to_base)


引数の意味
引数 説明
第1引数 変換する数値 (文字列または整数)
第2引数 元の基数 (2~36)
第3引数 変換先の基数 (2~36)


使用例を以下に示す。

 SELECT CONV('a', 16, 2);
 -- 結果: '1010' (16進数 'a' → 2進数)
 
 SELECT CONV('6E', 18, 8);
 -- 結果: '172' (18進数 '6E' → 8進数)
 
 SELECT CONV(10, 10, 16);
 -- 結果: 'A' (10進数 10 → 16進数)
 
 SELECT CONV('FF', 16, 10);
 -- 結果: '255' (16進数 'FF' → 10進数)
 
 SELECT CONV(255, 10, 2);
 -- 結果: '11111111' (10進数 255 → 2進数)
 
 SELECT CONV('100', 2, 10);
 -- 結果: '4' (2進数 '100' → 10進数)
 
 SELECT CONV('Z', 36, 10);
 -- 結果: '35' (36進数 'Z' → 10進数)


基数変換の実用例を以下に示す。

 -- 2進数 → 10進数
 SELECT CONV('11111111', 2, 10);
 -- 結果: '255'
 
 -- 10進数 → 16進数
 SELECT CONV(255, 10, 16);
 -- 結果: 'FF'
 
 -- 16進数 → 2進数
 SELECT CONV('FF', 16, 2);
 -- 結果: '11111111'


HEX / UNHEX

HEX 関数は、数値または文字列を16進数表現に変換する。
UNHEX 関数は、16進数表現をバイナリ文字列に変換する。

基本構文を以下に示す。

 HEX(n)
 HEX(str)
 UNHEX(str)


使用例を以下に示す。

 SELECT HEX(255);
 -- 結果: 'FF' (数値を16進数に変換)
 
 SELECT HEX(256);
 -- 結果: '100'
 
 SELECT HEX('abc');
 -- 結果: '616263' (文字列の各バイトを16進数に変換)
 
 SELECT UNHEX('4D7953514C');
 -- 結果: 'MySQL' (16進数をバイナリ文字列に変換)
 
 SELECT UNHEX(HEX('string'));
 -- 結果: 'string' (往復変換)
 
 SELECT HEX(0);
 -- 結果: '0'


HEX 関数 と CONV 関数の違いを以下に示す。

 SELECT HEX(255);
 -- 結果: 'FF'
 
 SELECT CONV(255, 10, 16);
 -- 結果: 'FF'
 
 -- 同じ結果だが、HEXは数値→16進数専用、CONVは任意基数変換


OCT

OCT 関数は、数値を8進数表現に変換する。

基本構文を以下に示す。

 OCT(n)


使用例を以下に示す。

 SELECT OCT(12);
 -- 結果: '14' (10進数 12 → 8進数)
 
 SELECT OCT(8);
 -- 結果: '10'
 
 SELECT OCT(255);
 -- 結果: '377'
 
 SELECT OCT(0);
 -- 結果: '0'


BIN

BIN 関数は、数値を2進数表現に変換する。

基本構文を以下に示す。

 BIN(n)


使用例を以下に示す。

 SELECT BIN(12);
 -- 結果: '1100' (10進数 12 → 2進数)
 
 SELECT BIN(255);
 -- 結果: '11111111'
 
 SELECT BIN(8);
 -- 結果: '1000'
 
 SELECT BIN(0);
 -- 結果: '0'
 
 SELECT BIN(1);
 -- 結果: '1'


CRC32

CRC32 関数は、CRC32チェックサムを計算する。
戻り値は32ビット符号なし整数である。

基本構文を以下に示す。

 CRC32(str)


使用例を以下に示す。

 SELECT CRC32('MySQL');
 -- 結果: 3259397556
 
 SELECT CRC32('mysql');
 -- 結果: 2501908538 (大文字小文字で異なる)
 
 SELECT CRC32('');
 -- 結果: 0
 
 SELECT CRC32(NULL);
 -- 結果: NULL


CRC32 関数の実用例を以下に示す。

 -- データ整合性チェック
 SELECT id, data, CRC32(data) AS checksum FROM files;
 
 -- チェックサム検証
 SELECT * FROM files WHERE CRC32(data) <> stored_checksum;
 
 -- ハッシュベースのパーティショニング
 SELECT CRC32(user_id) % 10 AS partition_id FROM users;


※注意

  • CRC32 関数は暗号学的ハッシュ関数ではない。
    セキュリティ用途には不適切
  • 衝突の可能性がある。
    異なる入力が同じCRC32値を生成する場合がある
  • データ整合性チェックやハッシュ分散に使用する。



数値関数を使用する場合の注意

浮動小数点の精度

FLOAT型 および DOUBLE型は、浮動小数点数であり、丸め誤差が発生する。
そのため、金額計算等の精度が重要な処理では、DECIMAL型の使用を推奨する。

浮動小数点の丸め誤差の例を以下に示す。

 SELECT 0.1 + 0.2 = 0.3;
 -- 結果: 0 (DOUBLE型では丸め誤差により不一致)
 
 SELECT 0.1 + 0.2;
 -- 結果: 0.30000000000000004 (誤差が発生)
 
 -- DECIMAL型を使用した正確な計算
 SELECT CAST(0.1 AS DECIMAL(10,1)) + CAST(0.2 AS DECIMAL(10,1))
        = CAST(0.3 AS DECIMAL(10,1));
 -- 結果: 1 (一致)
 
 SELECT CAST(0.1 AS DECIMAL(10,1)) + CAST(0.2 AS DECIMAL(10,1));
 -- 結果: 0.3 (正確)


金額計算の推奨例を以下に示す。

 -- 推奨: DECIMAL型を使用
 CREATE TABLE orders (
    id INT PRIMARY KEY,
    price DECIMAL(10, 2),
    quantity INT,
    total DECIMAL(10, 2)
 );
 
 -- 金額計算
 UPDATE orders SET total = price * quantity;
 
 -- 非推奨: FLOAT/DOUBLEは避ける
 CREATE TABLE orders_bad (
    id INT PRIMARY KEY,
    price DOUBLE,
    quantity INT,
    total DOUBLE
 );


浮動小数点比較の注意事項を以下に示す。

 -- 直接比較は避ける
 SELECT * FROM measurements WHERE value = 0.3;
 -- 丸め誤差により期待通りに動作しない可能性
 
 -- 範囲比較を推奨
 SELECT * FROM measurements WHERE ABS(value - 0.3) < 0.0001;
 -- 許容誤差内での比較


インデックスへの影響

WHERE句で数値関数を使用すると、インデックスが使用されない場合が多い。
これにより、クエリのパフォーマンスが大幅に低下する可能性がある。

インデックスが使用されない例
 -- インデックスが使用されない
 SELECT * FROM orders WHERE ROUND(price, 0) = 100;
 
 -- インデックスが使用されない
 SELECT * FROM products WHERE ABS(stock - 50) < 10;


インデックスを使用する改善例
 -- インデックスが使用される
 SELECT * FROM orders WHERE price >= 99.5 AND price < 100.5;
 
 -- インデックスが使用される
 SELECT * FROM products WHERE stock BETWEEN 40 AND 60;


関数ベースインデックス (Generated Column) を使用する例
 -- Generated Columnを作成
 ALTER TABLE orders ADD COLUMN price_rounded INT AS (ROUND(price, 0)) STORED;
 
 -- インデックスを作成
 CREATE INDEX idx_price_rounded ON orders(price_rounded);
 
 -- インデックスが使用される
 SELECT * FROM orders WHERE price_rounded = 100;


MySQL 8.0以降では、関数インデックスが直接サポートされている。

 -- MySQL 8.0以降
 CREATE INDEX idx_round_price ON orders((ROUND(price, 0)));
 
 -- インデックスが使用される
 SELECT * FROM orders WHERE ROUND(price, 0) = 100;


NULLの扱い

多くの数値関数は、NULL引数に対してNULLを返す。

NULL処理の例を以下に示す。

 SELECT ABS(NULL);
 -- 結果: NULL
 
 SELECT ROUND(NULL, 2);
 -- 結果: NULL
 
 SELECT SQRT(NULL);
 -- 結果: NULL
 
 SELECT 10 + NULL;
 -- 結果: NULL (算術演算でもNULL)
 
 SELECT 10 / NULL;
 -- 結果: NULL


NULLを扱う場合は、COALESCE 関数 や IFNULL 関数を併用することを推奨する。

 SELECT ROUND(COALESCE(price, 0), 2) FROM products;
 -- NULLを0で置換してから丸め
 
 SELECT IFNULL(quantity, 0) * price AS total FROM order_items;
 -- NULLを0で置換
 
 SELECT COALESCE(discount_rate, 0.0) FROM customers;
 -- NULL割引率を0.0で置換


NULL伝播の例を以下に示す。

 SELECT price + tax;
 -- priceまたはtaxがNULLなら結果はNULL
 
 SELECT COALESCE(price, 0) + COALESCE(tax, 0);
 -- NULLを0で置換してから加算