「MySQL - 数値関数」の版間の差分
ページの作成:「== 概要 == MySQLでは、データ型間の変換が頻繁に発生する。<br> 型変換には、暗黙的な変換と明示的な変換の2種類が存在する。<br> <br> 暗黙的な型変換は、演算や比較の際にMySQLが自動的に実行する変換である。<br> 明示的な型変換は、<code>CAST</code> 関数や <code>CONVERT</code> 関数を使用してユーザが指定する変換である。<br> <br> 暗黙的な型変換は、便利で…」 |
編集の要約なし |
||
| 1行目: | 1行目: | ||
== 概要 == | == 概要 == | ||
MySQLでは、豊富な数値関数が提供されており、算術演算、丸め処理、三角関数、対数関数、ビット演算等を実行できる。<br> | |||
これらの関数は、SELECT文、UPDATE文、WHERE句等で使用でき、データ分析や計算処理において重要な役割を果たす。<br> | |||
<br> | <br> | ||
数値関数は、整数型 (INT, BIGINT)、固定小数点型 (DECIMAL)、浮動小数点型 (FLOAT, DOUBLE) の各データ型に対応している。<br> | |||
ただし、浮動小数点型では丸め誤差が発生するため、金額計算等の精度が重要な処理ではDECIMAL型の使用を推奨する。<br> | |||
<br> | <br> | ||
MySQL 5.7とMySQL 8.0では、数値関数の動作に大きな差異はないが、一部の関数で精度や型推論の挙動が改善されている。<br> | |||
<br> | <br> | ||
集約関数 (<code>SUM</code>, <code>AVG</code>, <code>COUNT</code>, <code>MIN</code>, <code>MAX</code>等) については、[[MySQL - 集約関数]] を参照すること。<br> | |||
<code> | |||
<br> | <br> | ||
<u>数値関数を <code>WHERE</code> 句で使用すると、インデックスが使用されない場合が多い。</u><br> | |||
< | <u>パフォーマンスを考慮する場合は、関数を使用しないクエリ設計を検討する必要がある。</u><br> | ||
<br><br> | <br><br> | ||
== | == 算術演算子 == | ||
MySQLでは、基本的な算術演算子が提供されている。<br> | |||
これらの演算子は、数値型カラムの計算やSELECT文での即値計算に使用できる。<br> | |||
<br> | <br> | ||
==== | ==== 基本算術演算子 ==== | ||
MySQLで使用可能な基本算術演算子を以下に示す。<br> | |||
<br> | <br> | ||
<center> | <center> | ||
{| class="wikitable" | {| class="wikitable" | ||
|+ | |+ 基本算術演算子 | ||
! 演算子 !! 説明 !! 使用例 !! 結果 | |||
|- | |- | ||
| + || 加算 || 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 | |||
|} | |} | ||
</center> | </center> | ||
<br> | <br> | ||
基本的な使用例を以下に示す。<br> | |||
<br> | |||
算術演算子は、数値型カラム同士の計算だけでなく、即値との計算にも使用できる。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
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; | |||
</syntaxhighlight> | |||
<br> | |||
==== 除算の動作 ==== | |||
除算演算子 (/) と整数除算演算子 (DIV) の動作の違いを以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
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 (整数部分のみ) | |||
</syntaxhighlight> | |||
<br> | |||
除算演算子 (/) は、DECIMAL型の結果を返す。<br> | |||
整数除算演算子 (DIV) は、商の整数部分のみを返す。<br> | |||
<br> | |||
ゼロ除算の動作を以下に示す。<br> | |||
<br> | |||
<u>ゼロ除算は、エラーではなくNULLを返す。</u><br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
SELECT 10 / 0; | |||
-- 結果: NULL (ゼロ除算はNULLを返す) | |||
SELECT 10 DIV 0; | |||
-- 結果: NULL | |||
SELECT 10 / NULL; | |||
-- 結果: NULL | |||
</syntaxhighlight> | |||
<br> | |||
==== MOD (剰余) 演算 ==== | |||
剰余演算は、割り算の余りを返す。<br> | |||
<code>%</code> 演算子 と <code>MOD</code> 関数は同一の動作をする。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
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 | |||
</syntaxhighlight> | |||
<br> | |||
剰余演算の結果の符号は、被除数の符号に従う。<br> | |||
<br> | <br> | ||
剰余演算の実用例を以下に示す。<br> | |||
<br> | <br> | ||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
SELECT | -- 偶数・奇数の判定 | ||
-- | SELECT id, id % 2 AS is_odd FROM users; | ||
-- is_odd=0: 偶数、is_odd=1: 奇数 | |||
SELECT | -- 3件ごとにグループ分け | ||
SELECT id, id % 3 AS group_no FROM items; | |||
SELECT | -- 曜日計算 (0=日曜, 6=土曜) | ||
SELECT DAYOFWEEK(order_date) % 7 AS weekday FROM orders; | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
==== | ==== 演算精度と型の規則 ==== | ||
MySQLの算術演算では、オペランドのデータ型に応じて結果の型が決定される。<br> | |||
<br> | <br> | ||
型推論の規則を以下に示す。<br> | |||
<br> | <br> | ||
<center> | <center> | ||
{| class="wikitable" | {| class="wikitable" | ||
|+ | |+ 算術演算の型推論規則 | ||
! オペランド !! 結果型 !! 説明 | |||
|- | |- | ||
| 整数 + 整数 || BIGINT || 64ビット整数精度 | |||
|- | |- | ||
| | | DECIMAL + 整数 || DECIMAL || 固定小数点精度を保持 | ||
|- | |- | ||
| | | DECIMAL + DECIMAL || DECIMAL || より高い精度を採用 | ||
|- | |- | ||
| | | FLOAT/DOUBLE + 任意 || DOUBLE || 浮動小数点精度 | ||
|- | |- | ||
| | | 整数 / 整数 || DECIMAL || 除算結果は小数を含む可能性 | ||
|} | |} | ||
</center> | </center> | ||
<br> | <br> | ||
型推論の例を以下に示す。<br> | |||
<br> | <br> | ||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
SELECT | SELECT 10 + 20; | ||
-- | -- 結果型: BIGINT | ||
SELECT | SELECT 10.5 + 20; | ||
-- | -- 結果型: DECIMAL | ||
SELECT | SELECT 10.5 + 20.3; | ||
-- | -- 結果型: DECIMAL | ||
SELECT | SELECT 10.5E0 + 20; | ||
-- | -- 結果型: DOUBLE (科学記法を使用した場合は浮動小数点) | ||
SELECT | SELECT 3 / 2; | ||
-- 結果: 1 ( | -- 結果: 1.5000 (DECIMAL型) | ||
SELECT | SELECT CAST(3 AS DECIMAL) / CAST(2 AS DECIMAL); | ||
-- 結果: | -- 結果: 1.5000 | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
整数オーバーフローの動作を以下に示す。<br> | |||
<br> | <br> | ||
<u>オーバーフロー動作は、<code>sql_mode</code> 設定により変化する。</u><br> | |||
<u>デフォルトでは、オーバーフロー時にエラーが発生する。</u><br> | |||
<br> | <br> | ||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
-- BIGINT範囲: -9223372036854775808 ~ 9223372036854775807 | |||
-- | |||
SELECT | SELECT 9223372036854775807 + 1; | ||
-- | -- ERROR: BIGINT value is out of range (sql_modeによる) | ||
-- オーバーフロー許容モード (NO_UNSIGNED_SUBTRACTION無効) | |||
-- 結果: | SET sql_mode = ''; | ||
SELECT 9223372036854775807 + 1; | |||
-- 結果: 9223372036854775808 (BIGINT UNSIGNED範囲に昇格) | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<br><br> | |||
== 丸め関数 == | |||
丸め関数は、数値を指定された精度に丸める処理を実行する。<br> | |||
MySQLでは、<code>ROUND</code>, <code>TRUNCATE</code>, <code>CEIL</code>, <code>FLOOR</code> 等の丸め関数が提供されている。<br> | |||
<br> | <br> | ||
==== | ==== ROUND ==== | ||
<code>ROUND</code> 関数は、数値を指定された桁数に丸める。<br> | |||
<br> | <br> | ||
基本構文を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
ROUND(x) | |||
ROUND(x, d) | |||
</syntaxhighlight> | |||
<br> | <br> | ||
<center> | <center> | ||
{| class="wikitable" | {| class="wikitable" | ||
|+ | |+ 引数の意味 | ||
|- | |- | ||
! | ! 引数 !! 説明 | ||
|- | |- | ||
| | | 第1引数 || 対象数値 | ||
|- | |- | ||
| | | 第2引数 || 小数点以下の桁数 (省略時は0)。負の値を指定すると小数点より左側を丸める | ||
|} | |} | ||
</center> | </center> | ||
<br> | <br> | ||
丸め方式は、数値型により異なる。<br> | |||
* 正確値型 (DECIMAL) | |||
*: round half away from zero (四捨五入) | |||
* 近似値型 (FLOAT, DOUBLE) | |||
*: 実装依存 (銀行家の丸め/偶数丸めになる場合がある) | |||
<br> | <br> | ||
使用例を以下に示す。<br> | |||
<br> | <br> | ||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
SELECT | 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 | SELECT ROUND(2.55E0, 1); | ||
-- 結果: | -- 結果: 2.5 (近似値型で偶数丸めになる可能性) | ||
</syntaxhighlight> | |||
<br> | |||
負の桁数指定により、整数部分の丸めが可能である。<br> | |||
<br> | |||
浮動小数点型と正確値型の丸め動作の違いを以下に示す。<br> | |||
<br> | |||
<u>金額計算等の精度が重要な処理では、DECIMAL型の使用を推奨する。</u><br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
-- 正確値型 (DECIMAL) | |||
SELECT ROUND(2.5); | |||
-- 結果: 3 | |||
SELECT | SELECT ROUND(3.5); | ||
-- 結果: | -- 結果: 4 | ||
SELECT | -- 近似値型 (DOUBLE) | ||
-- 結果: | SELECT ROUND(2.5E0); | ||
-- 結果: 2 (偶数丸めの可能性) | |||
SELECT | SELECT ROUND(3.5E0); | ||
-- 結果: | -- 結果: 4 | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
==== | ==== TRUNCATE ==== | ||
<code>TRUNCATE</code> 関数は、小数部を切り捨てる。(0方向に切り捨て)<br> | |||
<br> | |||
基本構文を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
TRUNCATE(x, d) | |||
</syntaxhighlight> | |||
<br> | <br> | ||
<center> | <center> | ||
{| class="wikitable" | {| class="wikitable" | ||
|+ | |+ 引数の意味 | ||
|- | |- | ||
! | ! 引数 !! 説明 | ||
|- | |- | ||
| | | 第1引数 || 対象数値 | ||
|- | |- | ||
| | | 第2引数 || 小数点以下の桁数。負の値を指定すると小数点より左側を0にする | ||
|} | |} | ||
</center> | </center> | ||
<br> | <br> | ||
使用例を以下に示す。<br> | |||
<br> | <br> | ||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
SELECT 1 | SELECT TRUNCATE(1.999, 1); | ||
-- 結果: 1 ( | -- 結果: 1.9 (小数第2位以降を切り捨て) | ||
SELECT TRUNCATE(1.999, 0); | |||
-- 結果: 1 (小数部を切り捨て) | |||
SELECT | SELECT TRUNCATE(1.999, 2); | ||
-- 結果: 1 | -- 結果: 1.99 | ||
SELECT 1 | SELECT TRUNCATE(-1.999, 1); | ||
-- 結果: 1 ( | -- 結果: -1.9 (0方向に切り捨て) | ||
SELECT | SELECT TRUNCATE(122, -2); | ||
-- 結果: 1 ( | -- 結果: 100 (小数点より左側を0にする) | ||
SELECT TRUNCATE(123.456, -1); | |||
-- 結果: 120 | |||
SELECT TRUNCATE(123.456, -2); | |||
-- 結果: 100 | |||
</syntaxhighlight> | |||
<br> | |||
<code>TRUNCATE</code> 関数は、四捨五入を行わず、単純に切り捨てる。<br> | |||
<br> | |||
<code>ROUND</code> 関数と <code>TRUNCATE</code> 関数の違いを以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
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 | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
==== | ==== CEIL / CEILING ==== | ||
<code>CEIL</code> 関数 および <code>CEILING</code> 関数は、x以上の最小の整数を返す。<br> | |||
これらは同一の関数である。<br> | |||
<br> | |||
基本構文を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
CEIL(x) | |||
CEILING(x) | |||
</syntaxhighlight> | |||
<br> | <br> | ||
使用例を以下に示す。<br> | |||
<br> | <br> | ||
<code>CEIL</code> 関数は、切り上げ処理に相当する。<br> | |||
ただし、負数では動作が異なるため注意が必要である。<br> | |||
<br> | <br> | ||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
SELECT 1 | SELECT CEIL(1.23); | ||
-- 結果: | -- 結果: 2 | ||
SELECT CEILING(1.23); | |||
-- 結果: 2 | |||
SELECT | SELECT CEIL(-1.23); | ||
-- 結果: 1 ( | -- 結果: -1 (-1.23以上の最小の整数は-1) | ||
SELECT | SELECT CEIL(5); | ||
-- 結果: | -- 結果: 5 (整数の場合はそのまま) | ||
SELECT | SELECT CEIL(1.01); | ||
-- 結果: | -- 結果: 2 | ||
SELECT | SELECT CEIL(-1.01); | ||
-- 結果: 1 | -- 結果: -1 | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
==== | ==== FLOOR ==== | ||
<code>FLOOR</code> 関数は、x以下の最大の整数を返す。<br> | |||
<br> | <br> | ||
基本構文を以下に示す。<br> | |||
<br> | <br> | ||
<syntaxhighlight lang="mysql"> | |||
FLOOR(x) | |||
</syntaxhighlight> | |||
<br> | |||
使用例を以下に示す。<br> | |||
<br> | |||
<code>FLOOR</code> 関数は、切り捨て処理に相当する。<br> | |||
ただし、負数では <code>TRUNCATE</code> 関数と動作が異なる。<br> | |||
<br> | <br> | ||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
SELECT | SELECT FLOOR(1.23); | ||
-- 結果: 1 | -- 結果: 1 | ||
SELECT | SELECT FLOOR(-1.23); | ||
-- 結果: | -- 結果: -2 (-1.23以下の最大の整数は-2) | ||
SELECT | SELECT FLOOR(5); | ||
-- 結果: 0 ( | -- 結果: 5 | ||
SELECT FLOOR(1.99); | |||
-- 結果: 1 | |||
SELECT FLOOR(-1.01); | |||
-- 結果: -2 | |||
</syntaxhighlight> | |||
<br> | |||
<code>FLOOR</code> 関数 と <code>TRUNCATE</code> 関数の違いを以下に示す。<br> | |||
<br> | |||
<code>FLOOR</code> 関数は負の無限大方向に、<code>TRUNCATE</code> 関数は0方向に切り捨てる。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
SELECT FLOOR(1.99); | |||
-- 結果: 1 | |||
SELECT TRUNCATE(1.99, 0); | |||
-- 結果: 1 | |||
SELECT FLOOR(-1.99); | |||
-- 結果: -2 (負の無限大方向に切り捨て) | |||
SELECT TRUNCATE(-1.99, 0); | |||
-- 結果: -1 (0方向に切り捨て) | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<br><br> | <br><br> | ||
== | == 絶対値・符号関数 == | ||
==== ABS ==== | |||
<code>ABS</code> 関数は、絶対値を返す。<br> | |||
<br> | |||
基本構文を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
ABS(x) | |||
</syntaxhighlight> | |||
<br> | |||
使用例を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
SELECT ABS(-32); | |||
-- 結果: 32 | |||
SELECT ABS(32); | |||
-- 結果: 32 | |||
SELECT ABS(-123.45); | |||
-- 結果: 123.45 | |||
SELECT ABS(0); | |||
-- 結果: 0 | |||
SELECT ABS(NULL); | |||
-- 結果: NULL | |||
</syntaxhighlight> | |||
<br> | |||
<code>ABS</code> 関数の使用例を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
-- 残高の差分の絶対値を計算 | |||
SELECT account_id, ABS(balance - target_balance) AS diff FROM accounts; | |||
-- 絶対値で並べ替え | |||
SELECT value FROM measurements ORDER BY ABS(value); | |||
</syntaxhighlight> | |||
<br> | <br> | ||
==== | ==== SIGN ==== | ||
<code> | <code>SIGN</code> 関数は、数値の符号を返す。<br> | ||
<br> | <br> | ||
基本構文を以下に示す。<br> | 基本構文を以下に示す。<br> | ||
<br> | <br> | ||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
SIGN(x) | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | |||
戻り値を以下に示す。<br> | |||
<br> | <br> | ||
<center> | <center> | ||
{| class="wikitable" | {| class="wikitable" | ||
|+ <code> | |+ <code>SIGN</code> 関数の戻り値 | ||
! 引数 !! | |- | ||
! 引数 !! 戻り値 | |||
|- | |- | ||
| | | 負数 || -1 | ||
|- | |- | ||
| | | 0 || 0 | ||
|- | |- | ||
| | | 正数 || 1 | ||
|} | |} | ||
</center> | </center> | ||
<br> | <br> | ||
使用例を以下に示す。<br> | |||
<br> | <br> | ||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
SELECT | 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 | |||
</syntaxhighlight> | |||
<br> | |||
<code>SIGN</code> 関数の例を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
-- 入出金の種別を判定 | |||
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; | |||
</syntaxhighlight> | |||
<br><br> | |||
== 累乗・平方根関数 == | |||
==== POWER / POW ==== | |||
<code>POWER</code> 関数 および <code>POW</code> 関数は、xのy乗を返す。<br> | |||
これらは同一の関数である。<br> | |||
<br> | |||
基本構文を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
POWER(x, y) | |||
POW(x, y) | |||
</syntaxhighlight> | |||
<br> | |||
<u>戻り値はDOUBLE型である。</u><br> | |||
<br> | |||
使用例を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
SELECT POW(2, 3); | |||
-- 結果: 8 (2の3乗) | |||
SELECT POWER(2, 3); | |||
-- 結果: 8 | |||
SELECT POW(2, -2); | |||
-- 結果: 0.25 (2の-2乗 = 1/4) | |||
SELECT | SELECT POW(10, 2); | ||
-- 結果: | -- 結果: 100 | ||
SELECT | SELECT POW(2, 0); | ||
-- 結果: | -- 結果: 1 (任意の数の0乗は1) | ||
SELECT | SELECT POW(2, 0.5); | ||
-- 結果: | -- 結果: 1.4142135623730951 (2の平方根) | ||
SELECT | SELECT POW(4, 0.5); | ||
-- 結果: | -- 結果: 2 | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
<u>負の指数を指定することで、逆数の計算が可能である。</u><br> | |||
< | <br> | ||
<code> | 実用例を以下に示す。<br> | ||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
-- 複利計算 (元金 * (1 + 利率) ^ 年数) | |||
SELECT principal * POW(1 + interest_rate, years) AS future_value | |||
FROM investments; | |||
-- 2のn乗でビット計算 | |||
SELECT POW(2, bit_position) AS bit_value; | |||
</syntaxhighlight> | |||
<br> | |||
==== SQRT ==== | |||
<code>SQRT</code> 関数は、非負の平方根を返す。<br> | |||
<br> | <br> | ||
基本構文を以下に示す。<br> | 基本構文を以下に示す。<br> | ||
<br> | <br> | ||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
SQRT(x) | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
< | 負の値を指定した場合はNULLを返す。<br> | ||
<br> | <br> | ||
使用例を以下に示す。<br> | |||
<br> | <br> | ||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
SELECT | SELECT SQRT(4); | ||
-- 結果: | -- 結果: 2 | ||
SELECT SQRT(20); | |||
-- 結果: 4.47213595499958 | |||
SELECT SQRT(2); | |||
-- 結果: 1.4142135623730951 | |||
SELECT SQRT(0); | |||
-- 結果: 0 | |||
SELECT | SELECT SQRT(-16); | ||
-- 結果: | -- 結果: NULL (負数の平方根はNULL) | ||
SELECT | SELECT SQRT(NULL); | ||
-- 結果: | -- 結果: NULL | ||
</syntaxhighlight> | |||
<br> | |||
実用例を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
-- 2点間の距離を計算 (ピタゴラスの定理) | |||
SELECT SQRT(POW(x2 - x1, 2) + POW(y2 - y1, 2)) AS distance | |||
FROM points; | |||
SELECT | -- 標準偏差の計算 | ||
SELECT SQRT(AVG(POW(value - avg_value, 2))) AS std_dev FROM data; | |||
</syntaxhighlight> | |||
<br> | |||
==== EXP ==== | |||
<code>EXP</code> 関数は、eのx乗を返す。<br> | |||
eは自然対数の底 (2.71828...) である。<br> | |||
<br> | |||
基本構文を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
EXP(x) | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
使用例を以下に示す。<br> | |||
<br> | <br> | ||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
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 | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
<code>EXP</code> 関数は、自然対数関数 <code>LN</code> の逆関数である。<br> | |||
<br> | <br> | ||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
SELECT | SELECT EXP(LN(10)); | ||
-- 結果: | -- 結果: 10 | ||
SELECT | SELECT LN(EXP(5)); | ||
-- 結果: | -- 結果: 5 | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br><br> | |||
== 対数関数 == | |||
対数関数は、指数の逆演算を実行する。<br> | |||
MySQLでは、自然対数、常用対数、任意の底の対数を計算できる。<br> | |||
<br> | <br> | ||
==== | ==== LN / LOG ==== | ||
<code> | <code>LN</code> 関数は、自然対数 (底e) を返す。<br> | ||
<code>LOG</code> 関数は、引数が1つの場合は自然対数を返し、引数が2つの場合は任意の底の対数を返す。<br> | |||
<br> | |||
基本構文を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
LN(x) | |||
LOG(x) | |||
LOG(b, x) | |||
</syntaxhighlight> | |||
<br> | <br> | ||
<center> | <center> | ||
{| class="wikitable" | {| class="wikitable" | ||
|+ | |+ 引数の意味 | ||
|- | |- | ||
! 関数形式 !! 説明 | |||
|- | |- | ||
| | | LN(x) || xの自然対数 (底e) | ||
|- | |- | ||
| | | LOG(x) || xの自然対数 (LN(x)と同じ) | ||
|- | |- | ||
| | | LOG(b, x) || 底bに対するxの対数 | ||
|} | |} | ||
</center> | </center> | ||
<br> | <br> | ||
===== | <math>x \le 0</math> の場合は、<code>NULL</code> を返す。<br> | ||
< | <br> | ||
使用例を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
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 | |||
</syntaxhighlight> | |||
<br> | |||
任意の底の対数を計算する例を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
SELECT LOG(2, 1024); | |||
-- 結果: 10 (2^10 = 1024) | |||
SELECT LOG(3, 81); | |||
-- 結果: 4 (3^4 = 81) | |||
SELECT LOG(5, 625); | |||
-- 結果: 4 (5^4 = 625) | |||
</syntaxhighlight> | |||
<br> | <br> | ||
<code> | ==== LOG2 ==== | ||
<code>LOG2</code> 関数は、底2の対数を返す。<br> | |||
<br> | |||
基本構文を以下に示す。<br> | |||
<br> | <br> | ||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
SELECT | LOG2(x) | ||
-- 結果: | </syntaxhighlight> | ||
<br> | |||
使用例を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
SELECT LOG2(65536); | |||
-- 結果: 16 (2^16 = 65536) | |||
SELECT LOG2(256); | |||
-- 結果: 8 | |||
SELECT LOG2(2); | |||
-- 結果: 1 | |||
SELECT | SELECT LOG2(1); | ||
-- 結果: | -- 結果: 0 | ||
SELECT | SELECT LOG2(1024); | ||
-- 結果: | -- 結果: 10 | ||
</syntaxhighlight> | |||
<br> | |||
<code>LOG2</code> 関数は、ビット幅の計算に有用である。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
-- 値を表現するために必要なビット数 | |||
SELECT CEIL(LOG2(max_value + 1)) AS required_bits; | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
===== | ==== LOG10 ==== | ||
<code>LOG10</code> 関数は、常用対数 (底が10) を返す。<br> | |||
<br> | |||
基本構文を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
LOG10(x) | |||
</syntaxhighlight> | |||
<br> | |||
使用例を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
SELECT LOG10(100); | |||
-- 結果: 2 (10^2 = 100) | |||
SELECT LOG10(1000); | |||
-- 結果: 3 | |||
SELECT LOG10(10); | |||
-- 結果: 1 | |||
SELECT LOG10(1); | |||
-- 結果: 0 | |||
SELECT LOG10(1000000); | |||
-- 結果: 6 | |||
</syntaxhighlight> | |||
<br> | |||
<code>LOG10</code> 関数は、桁数の計算に有用である。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
-- 正の整数の桁数を計算 | |||
SELECT FLOOR(LOG10(value)) + 1 AS digit_count FROM numbers; | |||
</syntaxhighlight> | |||
<br><br> | |||
== 三角関数 == | |||
MySQLでは、基本三角関数、逆三角関数、角度変換関数が提供されている。<br> | |||
全ての三角関数は、引数をラジアンで受け取る。<br> | |||
<br> | |||
==== 基本三角関数 ==== | |||
下表に、基本的な三角関数を示す。<br> | |||
<br> | <br> | ||
<center> | <center> | ||
{| class="wikitable" | {| class="wikitable" | ||
|+ | |+ 基本三角関数 | ||
! | ! 関数 !! 説明 !! 使用例 !! 結果 | ||
|- | |- | ||
| | | 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 | ||
| | |||
| | |||
|} | |} | ||
</center> | </center> | ||
<br> | <br> | ||
< | 使用例を以下に示す。<br> | ||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
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 | |||
</syntaxhighlight> | |||
<br> | |||
==== 逆三角関数 ==== | |||
逆三角関数は、三角関数の逆演算を実行する。<br> | |||
戻り値はラジアンである。<br> | |||
<br> | <br> | ||
<center> | <center> | ||
{| class="wikitable" | {| class="wikitable" | ||
|+ | |+ 逆三角関数 | ||
! 関数 !! 説明 !! 定義域 !! 値域 | |||
|- | |- | ||
| ASIN(x) || 逆正弦 (アークサイン) || -1 ≤ x ≤ 1 || -π/2 ~ π/2 | |||
|- | |- | ||
| | | ACOS(x) || 逆余弦 (アークコサイン) || -1 ≤ x ≤ 1 || 0 ~ π | ||
|- | |- | ||
| | | ATAN(x) || 逆正接 (アークタンジェント) || 全ての実数 || -π/2 ~ π/2 | ||
|- | |||
| ATAN2(y, x) || 2引数逆正接 || 全ての実数 || -π ~ π | |||
|} | |} | ||
</center> | </center> | ||
<br> | <br> | ||
使用例を以下に示す。<br> | |||
<br> | <br> | ||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
SELECT | SELECT ASIN(1); | ||
-- 結果: | -- 結果: 1.5707963267948966 (π/2、90度) | ||
SELECT ACOS(-1); | |||
-- 結果: 3.141592653589793 (π、180度) | |||
SELECT | SELECT ATAN(1); | ||
-- 結果: | -- 結果: 0.7853981633974483 (π/4、45度) | ||
SELECT | SELECT ATAN2(1, 1); | ||
-- 結果: | -- 結果: 0.7853981633974483 (π/4、45度) | ||
SELECT | SELECT ASIN(2); | ||
-- 結果: | -- 結果: NULL (定義域外) | ||
SELECT | SELECT ASIN(-1); | ||
-- 結果: | -- 結果: -1.5707963267948966 (-π/2、-90度) | ||
</syntaxhighlight> | |||
<br> | |||
<code>ATAN2</code> 関数は、座標 (x, y) の角度を計算する場合に有用である。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
SELECT ATAN2(1, 0); | |||
-- 結果: 1.5707963267948966 (π/2、90度、y軸正方向) | |||
SELECT | SELECT ATAN2(0, 1); | ||
-- 結果: | -- 結果: 0 (x軸正方向) | ||
SELECT | SELECT ATAN2(-1, 0); | ||
-- 結果: | -- 結果: -1.5707963267948966 (-π/2、-90度、y軸負方向) | ||
SELECT | SELECT ATAN2(0, -1); | ||
-- 結果: | -- 結果: 3.141592653589793 (π、180度、x軸負方向) | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
==== | ==== 角度変換 ==== | ||
角度変換関数により、ラジアンと度の相互変換が可能である。<br> | |||
<br> | <br> | ||
<center> | <center> | ||
{| class="wikitable" | {| class="wikitable" | ||
|+ | |+ 角度変換関数 | ||
! | ! 関数 !! 説明 !! 使用例 !! 結果 | ||
|- | |- | ||
| | | DEGREES(x) || ラジアン → 度 || SELECT DEGREES(PI()) || 180 | ||
|- | |- | ||
| | | RADIANS(x) || 度 → ラジアン || SELECT RADIANS(180) || 3.141592653589793 | ||
|} | |} | ||
</center> | </center> | ||
<br> | <br> | ||
使用例を以下に示す。<br> | |||
<br> | <br> | ||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
SELECT | SELECT DEGREES(PI()); | ||
-- 結果: | -- 結果: 180 | ||
SELECT DEGREES(PI()/2); | |||
-- 結果: 90 | |||
SELECT | SELECT RADIANS(180); | ||
-- 結果: | -- 結果: 3.141592653589793 (π) | ||
SELECT | SELECT RADIANS(90); | ||
-- 結果: | -- 結果: 1.5707963267948966 (π/2) | ||
SELECT | SELECT RADIANS(360); | ||
-- 結果: | -- 結果: 6.283185307179586 (2π) | ||
</syntaxhighlight> | |||
<br> | |||
度単位での三角関数計算例を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
SELECT SIN(RADIANS(30)); | |||
-- 結果: 0.49999999999999994 (約0.5、30度のサイン) | |||
SELECT | SELECT COS(RADIANS(60)); | ||
-- 結果: | -- 結果: 0.5000000000000001 (約0.5、60度のコサイン) | ||
SELECT | SELECT DEGREES(ASIN(0.5)); | ||
-- 結果 | -- 結果: 30.000000000000004 (約30度) | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
<code> | ==== PI ==== | ||
<code>PI</code> 関数は、円周率πの値を返す。<br> | |||
<br> | |||
基本構文を以下に示す。<br> | |||
<br> | <br> | ||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
PI() | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
使用例を以下に示す。<br> | |||
<br> | <br> | ||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
SELECT | SELECT PI(); | ||
-- 結果: | -- 結果: 3.141593 (表示精度は倍精度) | ||
SELECT | SELECT PI() * 2; | ||
-- 結果: | -- 結果: 6.283185307179586 (2π) | ||
SELECT | 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; | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<br><br> | <br><br> | ||
== | == ランダム関数 == | ||
MySQLでは、乱数生成関数が提供されている。<br> | |||
<br> | |||
==== RAND ==== | |||
<code>RAND</code> 関数は、0以上1未満の乱数を返す。<br> | |||
戻り値の型は、<code>DOUBLE</code> である。<br> | |||
<br> | <br> | ||
基本構文を以下に示す。<br> | |||
<br> | <br> | ||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
RAND() | |||
-- 結果: | RAND(seed) | ||
</syntaxhighlight> | |||
<br> | |||
<center> | |||
{| class="wikitable" | |||
|+ 引数の意味 | |||
|- | |||
! 形式 !! 説明 | |||
|- | |||
| RAND() || ランダムな乱数を生成 | |||
|- | |||
| RAND(seed) || シード値を指定して再現可能な乱数列を生成 | |||
|} | |||
</center> | |||
<br> | |||
使用例を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
SELECT RAND(); | |||
-- 結果: 0.6912345678901234 (実行ごとに異なる) | |||
SELECT | SELECT RAND(); | ||
-- 結果: | -- 結果: 0.1234567890123456 (毎回異なる値) | ||
SELECT | SELECT RAND(100); | ||
-- 結果: | -- 結果: 0.9546361446761204 (シード100の場合は常に同じ値) | ||
SELECT | SELECT RAND(100); | ||
-- 結果: | -- 結果: 0.9546361446761204 (シードが同じなら同じ値) | ||
SELECT | SELECT RAND(200); | ||
-- 結果: | -- 結果: 0.44880484265643147 (異なるシード) | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
シード値を指定することで、再現可能な乱数列を生成できる。<br> | |||
これは、テストデータ生成時に有用である。<br> | |||
<br> | |||
整数範囲の乱数を生成する例を以下に示す。<br> | |||
<br> | <br> | ||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
-- 1~6のランダム整数 (サイコロ) | |||
SELECT FLOOR(RAND() * 6) + 1; | |||
SELECT | -- 0~99のランダム整数 | ||
SELECT FLOOR(RAND() * 100); | |||
SELECT | -- min~maxのランダム整数 | ||
SELECT FLOOR(RAND() * (max - min + 1)) + min; | |||
SELECT | -- 10~20のランダム整数 | ||
SELECT FLOOR(RAND() * 11) + 10; | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
ランダムにレコードを取得する例を以下に示す。<br> | |||
<br> | <br> | ||
<code> | <syntaxhighlight lang="mysql"> | ||
-- ランダムに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(); | |||
</syntaxhighlight> | |||
<br> | |||
<u>※注意</u><br> | |||
* <u><code>ORDER BY RAND()</code> は、全行に対して乱数を生成してソートするため、大量データでは非常に遅い。</u> | |||
*: 代替手法として、ランダムなIDを生成してWHERE句で絞り込む方法が推奨される。 | |||
* <u>行ごとに <code>RAND()</code> の値は異なる。</u> | |||
*: 複数カラムで同一の乱数を使用する場合は、ユーザ変数を使用する。 | |||
<br> | |||
大量データでのランダム抽出の代替手法を以下に示す。<br> | |||
<br> | <br> | ||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
-- 代替手法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; | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<br><br> | |||
== ビット演算 == | |||
MySQLでは、整数値に対するビット演算が可能である。<br> | |||
MySQL 8.0以降では、<u>64ビット整数 (BIGINT)</u> と <u>バイナリ文字列</u> の両方に対応している。<br> | |||
<br> | |||
==== ビット演算子 ==== | |||
ビット演算子を以下に示す。<br> | |||
<br> | <br> | ||
<center> | <center> | ||
{| class="wikitable" | {| class="wikitable" | ||
|+ | |+ ビット演算子 | ||
! | ! 演算子 !! 説明 !! 使用例 !! 結果 | ||
|- | |||
| & || ビットAND || SELECT 29 & 15 || 13 | |||
|- | |- | ||
| < | | <nowiki>|</nowiki> || ビットOR || SELECT 29 <nowiki>|</nowiki> 15 || 31 | ||
|- | |- | ||
| | | ^ || ビットXOR (排他的論理和) || SELECT 29 ^ 15 || 18 | ||
|- | |- | ||
| | | ~ || ビットNOT (反転) || SELECT ~0 || 18446744073709551615 | ||
|- | |- | ||
| < | | << || 左シフト || SELECT 1 << 4 || 16 | ||
|- | |- | ||
| | | >> || 右シフト || SELECT 16 >> 2 || 4 | ||
|} | |} | ||
</center> | </center> | ||
<br> | <br> | ||
下表に、戻り値を示す。<br> | |||
<br> | <br> | ||
<center> | <center> | ||
{| class="wikitable" | {| class="wikitable" | ||
|+ | |+ <code>BIT_NOT</code> 関数の戻り値の型 | ||
|- | |||
! 引数の型 !! 戻り値の型 | |||
|- | |||
| 整数の場合 || BIGINT UNSIGNED (64ビット符号なし整数) | |||
|- | |- | ||
| バイナリ文字列の場合 || 同じ長さのバイナリ文字列 | |||
|} | |||
</center> | |||
<br> | |||
使用例を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
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 | |||
</syntaxhighlight> | |||
<br> | |||
ビット演算の詳細な例を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
-- 特定ビットのチェック | |||
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ビット内で反転) | |||
</syntaxhighlight> | |||
<br> | |||
==== BIT_COUNT ==== | |||
<code>BIT_COUNT</code> 関数は、セットされたビット (1のビット) の数を返す。<br> | |||
<br> | |||
基本構文を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
BIT_COUNT(n) | |||
</syntaxhighlight> | |||
<br> | |||
使用例を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
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) | |||
</syntaxhighlight> | |||
<br> | |||
==== ビット演算の応用例 ==== | |||
===== フラグ管理 ===== | |||
<syntaxhighlight lang="mysql"> | |||
-- 権限フラグの定義 | |||
-- 読み取り: 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; | |||
</syntaxhighlight> | |||
<br> | |||
===== IPアドレスのネットワークアドレス計算 ===== | |||
<syntaxhighlight lang="mysql"> | |||
-- 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' | |||
</syntaxhighlight> | |||
<br> | |||
===== 2の累乗判定 ===== | |||
<syntaxhighlight lang="mysql"> | |||
-- 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の累乗ではない) | |||
</syntaxhighlight> | |||
<br><br> | |||
== 変換・フォーマット関数 == | |||
数値を異なる形式に変換・フォーマットする関数を以下に示す。<br> | |||
<br> | |||
==== FORMAT ==== | |||
<code>FORMAT</code> 関数は、数値を千の位区切りでフォーマットする。<br> | |||
戻り値は文字列である。<br> | |||
<br> | |||
基本構文を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
FORMAT(x, d) | |||
FORMAT(x, d, locale) | |||
</syntaxhighlight> | |||
<br> | |||
<center> | |||
{| class="wikitable" | |||
|+ 引数の意味 | |||
|- | |- | ||
! 引数 !! 説明 | |||
|- | |- | ||
| | | 第1引数 || 対象数値 | ||
|- | |- | ||
| | | 第2引数 || 小数点以下の桁数 | ||
|- | |- | ||
| | | 第3引数 || ロケール (省略時は en_US) | ||
|} | |} | ||
</center> | </center> | ||
<br> | <br> | ||
使用例を以下に示す。<br> | |||
<br> | <br> | ||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
SELECT FORMAT(12332.123456, 4); | |||
-- 結果: '12,332.1235' (小数第5位を四捨五入) | |||
SELECT | |||
-- 結果: ' | |||
SELECT | SELECT FORMAT(12332.1, 4); | ||
-- 結果: | -- 結果: '12,332.1000' (小数点以下を0でパディング) | ||
SELECT | SELECT FORMAT(12332.2, 0); | ||
-- 結果: | -- 結果: '12,332' (整数部のみ) | ||
SELECT | SELECT FORMAT(1234567.89, 2); | ||
-- 結果: | -- 結果: '1,234,567.89' | ||
SELECT | SELECT FORMAT(1234567.89, 2, 'de_DE'); | ||
-- 結果: | -- 結果: '1.234.567,89' (ドイツ語ロケール) | ||
SELECT | SELECT FORMAT(12332.2, 2, 'de_DE'); | ||
-- | -- 結果: '12.332,20' | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
ロケールによる表示形式の違いを以下に示す。<br> | |||
<br> | <br> | ||
<center> | <center> | ||
{| class="wikitable" | {| class="wikitable" | ||
|+ | |+ ロケールによる表示形式 | ||
! | ! ロケール !! 千の位区切り !! 小数点記号 !! 例 | ||
|- | |- | ||
| | | en_US || カンマ (,) || ピリオド (.) || 1,234.56 | ||
|- | |- | ||
| | | de_DE || ピリオド (.) || カンマ (,) || 1.234,56 | ||
|- | |- | ||
| <code> | | fr_FR || スペース || カンマ (,) || 1 234,56 | ||
|} | |||
</center> | |||
<br> | |||
==== CONV ==== | |||
<code>CONV</code> 関数は、異なる基数 (進数) 間で数値を変換する。<br> | |||
2進数から36進数までの変換が可能である。<br> | |||
<br> | |||
基本構文を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
CONV(n, from_base, to_base) | |||
</syntaxhighlight> | |||
<br> | |||
<center> | |||
{| class="wikitable" | |||
|+ 引数の意味 | |||
|- | |||
! 引数 !! 説明 | |||
|- | |- | ||
| | | 第1引数 || 変換する数値 (文字列または整数) | ||
|- | |- | ||
| | | 第2引数 || 元の基数 (2~36) | ||
|- | |- | ||
| | | 第3引数 || 変換先の基数 (2~36) | ||
|} | |} | ||
</center> | </center> | ||
<br> | <br> | ||
< | 使用例を以下に示す。<br> | ||
< | <br> | ||
<syntaxhighlight lang="mysql"> | |||
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進数) | |||
</syntaxhighlight> | |||
<br> | <br> | ||
基数変換の実用例を以下に示す。<br> | |||
<br> | <br> | ||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
-- 2進数 → 10進数 | |||
SELECT CONV('11111111', 2, 10); | |||
-- 結果: '255' | |||
SELECT | -- 10進数 → 16進数 | ||
-- 結果: | SELECT CONV(255, 10, 16); | ||
-- 結果: 'FF' | |||
SELECT | -- 16進数 → 2進数 | ||
-- 結果: | SELECT CONV('FF', 16, 2); | ||
-- 結果: '11111111' | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
==== HEX / UNHEX ==== | |||
<code>HEX</code> 関数は、数値または文字列を16進数表現に変換する。<br> | |||
<code>UNHEX</code> 関数は、16進数表現をバイナリ文字列に変換する。<br> | |||
<br> | |||
基本構文を以下に示す。<br> | |||
<br> | <br> | ||
<syntaxhighlight lang="mysql"> | |||
HEX(n) | |||
HEX(str) | |||
UNHEX(str) | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | |||
使用例を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
SELECT | 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' | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | |||
<code>HEX</code> 関数 と <code>CONV</code> 関数の違いを以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
SELECT | SELECT HEX(255); | ||
-- 結果: | -- 結果: 'FF' | ||
SELECT | SELECT CONV(255, 10, 16); | ||
-- 結果: | -- 結果: 'FF' | ||
-- 同じ結果だが、HEXは数値→16進数専用、CONVは任意基数変換 | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | |||
==== OCT ==== | |||
<code>OCT</code> 関数は、数値を8進数表現に変換する。<br> | |||
<br> | |||
基本構文を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
OCT(n) | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
使用例を以下に示す。<br> | |||
<br> | <br> | ||
<syntaxhighlight lang="mysql"> | |||
SELECT OCT(12); | |||
-- | -- 結果: '14' (10進数 12 → 8進数) | ||
SELECT | |||
-- | SELECT OCT(8); | ||
-- 結果: '10' | |||
SELECT OCT(255); | |||
-- 結果: '377' | |||
SELECT OCT(0); | |||
SELECT | -- 結果: '0' | ||
-- | </syntaxhighlight> | ||
<br> | |||
==== BIN ==== | |||
<code>BIN</code> 関数は、数値を2進数表現に変換する。<br> | |||
<br> | |||
基本構文を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
BIN(n) | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | |||
使用例を以下に示す。<br> | |||
<br> | |||
-- | <syntaxhighlight lang="mysql"> | ||
SELECT | SELECT BIN(12); | ||
-- | -- 結果: '1100' (10進数 12 → 2進数) | ||
SELECT BIN(255); | |||
-- 結果: '11111111' | |||
SELECT BIN(8); | |||
-- 結果: '1000' | |||
SELECT BIN(0); | |||
-- 結果: '0' | |||
SELECT BIN(1); | |||
-- 結果: '1' | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
< | ==== CRC32 ==== | ||
<code>CRC32</code> 関数は、CRC32チェックサムを計算する。<br> | |||
戻り値は32ビット符号なし整数である。<br> | |||
<br> | |||
基本構文を以下に示す。<br> | |||
<br> | <br> | ||
= | <syntaxhighlight lang="mysql"> | ||
CRC32(str) | |||
</syntaxhighlight> | |||
<br> | |||
使用例を以下に示す。<br> | |||
<br> | <br> | ||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
SELECT | SELECT CRC32('MySQL'); | ||
-- 結果: 3259397556 | |||
SELECT CRC32('mysql'); | |||
-- 結果: 2501908538 (大文字小文字で異なる) | |||
SELECT CRC32(''); | |||
-- 結果: 0 | |||
SELECT CRC32(NULL); | |||
-- 結果: NULL | -- 結果: NULL | ||
</syntaxhighlight> | |||
<br> | |||
<code>CRC32</code> 関数の実用例を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
-- データ整合性チェック | |||
SELECT id, data, CRC32(data) AS checksum FROM files; | |||
-- チェックサム検証 | |||
SELECT * FROM files WHERE CRC32(data) <> stored_checksum; | |||
SELECT CAST( | -- ハッシュベースのパーティショニング | ||
-- 結果: | SELECT CRC32(user_id) % 10 AS partition_id FROM users; | ||
</syntaxhighlight> | |||
<br> | |||
<u>※注意</u><br> | |||
* <u><code>CRC32</code> 関数は暗号学的ハッシュ関数ではない。</u> | |||
*: セキュリティ用途には不適切 | |||
* <u>衝突の可能性がある。</u> | |||
*: 異なる入力が同じCRC32値を生成する場合がある | |||
* <u>データ整合性チェックやハッシュ分散に使用する。</u> | |||
<br><br> | |||
== 数値関数を使用する場合の注意 == | |||
==== 浮動小数点の精度 ==== | |||
<u>FLOAT型 および DOUBLE型は、浮動小数点数であり、丸め誤差が発生する。</u><br> | |||
<u>そのため、金額計算等の精度が重要な処理では、DECIMAL型の使用を推奨する。</u><br> | |||
<br> | |||
浮動小数点の丸め誤差の例を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
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 (正確) | |||
</syntaxhighlight> | |||
<br> | |||
金額計算の推奨例を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
-- 推奨: 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 | |||
); | |||
</syntaxhighlight> | |||
<br> | |||
浮動小数点比較の注意事項を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | |||
-- 直接比較は避ける | |||
SELECT * FROM measurements WHERE value = 0.3; | |||
-- 丸め誤差により期待通りに動作しない可能性 | |||
SELECT | -- 範囲比較を推奨 | ||
-- | SELECT * FROM measurements WHERE ABS(value - 0.3) < 0.0001; | ||
-- 許容誤差内での比較 | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
< | ==== インデックスへの影響 ==== | ||
<u>WHERE句で数値関数を使用すると、インデックスが使用されない場合が多い。</u><br> | |||
<u>これにより、クエリのパフォーマンスが大幅に低下する可能性がある。</u><br> | |||
<br> | |||
===== インデックスが使用されない例 ===== | |||
<syntaxhighlight lang="mysql"> | |||
-- インデックスが使用されない | |||
SELECT * FROM orders WHERE ROUND(price, 0) = 100; | |||
-- インデックスが使用されない | |||
SELECT * FROM products WHERE ABS(stock - 50) < 10; | |||
</syntaxhighlight> | |||
<br> | <br> | ||
===== インデックスを使用する改善例 ===== | |||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
SELECT | -- インデックスが使用される | ||
SELECT * FROM orders WHERE price >= 99.5 AND price < 100.5; | |||
-- インデックスが使用される | |||
SELECT * FROM products WHERE stock BETWEEN 40 AND 60; | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
==== | ===== 関数ベースインデックス (Generated Column) を使用する例 ===== | ||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
-- | -- 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 | SELECT * FROM orders WHERE price_rounded = 100; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
MySQL 8.0以降では、関数インデックスが直接サポートされている。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
-- MySQL 8.0以降 | |||
CREATE INDEX idx_round_price ON orders((ROUND(price, 0))); | |||
-- | -- インデックスが使用される | ||
SELECT | SELECT * FROM orders WHERE ROUND(price, 0) = 100; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
==== | ==== NULLの扱い ==== | ||
<u>多くの数値関数は、NULL引数に対してNULLを返す。</u><br> | |||
<br> | |||
NULL処理の例を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
SELECT | SELECT ABS(NULL); | ||
-- 結果: | -- 結果: NULL | ||
SELECT ROUND(NULL, 2); | |||
-- 結果: NULL | |||
SELECT SQRT(NULL); | |||
-- 結果: NULL | |||
SELECT | SELECT 10 + NULL; | ||
-- 結果: | -- 結果: NULL (算術演算でもNULL) | ||
SELECT 10 / NULL; | |||
SELECT | -- 結果: NULL | ||
-- 結果: | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
NULLを扱う場合は、<code>COALESCE</code> 関数 や <code>IFNULL</code> 関数を併用することを推奨する。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
SELECT | 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; | |||
SELECT | -- NULL割引率を0.0で置換 | ||
-- | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<br> | <br> | ||
NULL伝播の例を以下に示す。<br> | |||
<br> | |||
<syntaxhighlight lang="mysql"> | <syntaxhighlight lang="mysql"> | ||
SELECT | SELECT price + tax; | ||
-- | -- priceまたはtaxがNULLなら結果はNULL | ||
SELECT COALESCE(price, 0) + COALESCE(tax, 0); | |||
SELECT | -- NULLを0で置換してから加算 | ||
-- | |||
</syntaxhighlight> | </syntaxhighlight> | ||
<br><br> | <br><br> | ||
| 819行目: | 1,708行目: | ||
{{#seo: | {{#seo: | ||
|title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki | |title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki | ||
|keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,MySQL,Database,SQL, | |keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,MySQL,Database,SQL,Numeric Functions,Math Functions,ROUND,ABS,SQRT,SIN,COS,POWER,LOG,数値関数,算術演算,三角関数,データベース,電気回路,電子回路,基板,プリント基板 | ||
|description={{PAGENAME}} - | |description={{PAGENAME}} - MySQLの数値関数に関する包括的なリファレンス | This page is {{PAGENAME}} in our wiki about electronic circuits and SUSE Linux | ||
|image=/resources/assets/MochiuLogo_Single_Blue.png | |image=/resources/assets/MochiuLogo_Single_Blue.png | ||
}} | }} | ||
2026年2月16日 (月) 17:25時点における最新版
概要
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)
戻り値を以下に示す。
| 引数 | 戻り値 |
|---|---|
| 負数 | -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の対数 |
の場合は、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 |
下表に、戻り値を示す。
| 引数の型 | 戻り値の型 |
|---|---|
| 整数の場合 | 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で置換してから加算