「MySQL - 数値関数」の版間の差分

提供: MochiuWiki : SUSE, EC, PCB

ページの作成:「== 概要 == MySQLでは、データ型間の変換が頻繁に発生する。<br> 型変換には、暗黙的な変換と明示的な変換の2種類が存在する。<br> <br> 暗黙的な型変換は、演算や比較の際にMySQLが自動的に実行する変換である。<br> 明示的な型変換は、<code>CAST</code> 関数や <code>CONVERT</code> 関数を使用してユーザが指定する変換である。<br> <br> 暗黙的な型変換は、便利で…」
 
編集の要約なし
 
1行目: 1行目:
== 概要 ==
== 概要 ==
MySQLでは、データ型間の変換が頻繁に発生する。<br>
MySQLでは、豊富な数値関数が提供されており、算術演算、丸め処理、三角関数、対数関数、ビット演算等を実行できる。<br>
型変換には、暗黙的な変換と明示的な変換の2種類が存在する。<br>
これらの関数は、SELECT文、UPDATE文、WHERE句等で使用でき、データ分析や計算処理において重要な役割を果たす。<br>
<br>
<br>
暗黙的な型変換は、演算や比較の際にMySQLが自動的に実行する変換である。<br>
数値関数は、整数型 (INT, BIGINT)、固定小数点型 (DECIMAL)、浮動小数点型 (FLOAT, DOUBLE) の各データ型に対応している。<br>
明示的な型変換は、<code>CAST</code> 関数や <code>CONVERT</code> 関数を使用してユーザが指定する変換である。<br>
ただし、浮動小数点型では丸め誤差が発生するため、金額計算等の精度が重要な処理ではDECIMAL型の使用を推奨する。<br>
<br>
<br>
暗黙的な型変換は、便利である一方で、予期しない結果やパフォーマンスの低下を引き起こす場合がある。<br>
MySQL 5.7とMySQL 8.0では、数値関数の動作に大きな差異はないが、一部の関数で精度や型推論の挙動が改善されている。<br>
特に、WHERE句でカラムに対して型変換が適用されると、インデックスが使用されなくなる可能性が高い。<br>
<br>
<br>
MySQL 8.0.17以降では、<code>CAST</code> 関数 および <code>CONVERT</code> 関数で使用可能な型が拡張されている。<br>
集約関数 (<code>SUM</code>, <code>AVG</code>, <code>COUNT</code>, <code>MIN</code>, <code>MAX</code>等) については、[[MySQL - 集約関数]] を参照すること。<br>
<code>FLOAT</code> 型、<code>DOUBLE</code> 型への変換がサポートされ、精度指定も可能になった。<br>
<br>
<br>
また、MySQL 8.0.22以降では、<code>YEAR</code> 型への変換、および <code>AT TIME ZONE</code> 演算子が追加された。<br>
<u>数値関数を <code>WHERE</code> 句で使用すると、インデックスが使用されない場合が多い。</u><br>
<br>
<u>パフォーマンスを考慮する場合は、関数を使用しないクエリ設計を検討する必要がある。</u><br>
型変換の動作を正確に理解することは、データの整合性を保ち、パフォーマンスを最適化する上で重要である。<br>
<br><br>
<br><br>


== 暗黙的な型変換 ==
== 算術演算子 ==
暗黙的な型変換は、MySQLが自動的に実行する型変換である。<br>
MySQLでは、基本的な算術演算子が提供されている。<br>
演算子や関数が異なる型の引数を受け取った場合、MySQLは自動的に型を変換して処理を行う。<br>
これらの演算子は、数値型カラムの計算やSELECT文での即値計算に使用できる。<br>
<br>
<br>
==== 暗黙的変換が発生する場面 ====
==== 基本算術演算子 ====
暗黙的な型変換は、以下に示す場面で発生する。<br>
MySQLで使用可能な基本算術演算子を以下に示す。<br>
<br>
<br>
<center>
<center>
{| class="wikitable"
{| class="wikitable"
|+ 暗黙的な型変換が発生する場面
|+ 基本算術演算子
! 演算子 !! 説明 !! 使用例 !! 結果
|-
|-
! 場面 !! 説明
| + || 加算 || SELECT 10 + 5 || 15
|-
|-
| 比較演算子を使用する場合 || <code>=</code>、<code>!=</code>、<code>&lt;</code>、<code>&gt;</code>、<code>&lt;=</code>、<code>&gt;=</code> 等
| - || 減算 || SELECT 10 - 5 || 5
|-
|-
| 算術演算子を使用する場合 || <code>+</code>、<code>-</code>、<code>*</code>、<code>/</code>、<code>%</code> 等
| * || 乗算 || SELECT 10 * 5 || 50
|-
|-
| 関数の引数として使用する場合 || <code>CONCAT</code> 関数、<code>SUBSTRING</code> 関数等
| / || 除算 || SELECT 10 / 5 || 2.0000
|-
|-
| INSERT文またはUPDATE文での値代入 || カラムの型と異なる型の値を挿入または更新する場合
| DIV || 整数除算 || SELECT 10 DIV 3 || 3
|-
|-
| WHERE句での条件評価 || カラムと異なる型の値で比較する場合
| % || 剰余 (MOD) || SELECT 10 % 3 || 1
|-
| MOD || 剰余 (関数形式) || SELECT MOD(10, 3) || 1
|}
|}
</center>
</center>
<br>
<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>
<u>暗黙的変換は、コードの記述を簡潔にする一方で、予期しない動作を引き起こす可能性がある。</u><br>
剰余演算の実用例を以下に示す。<br>
<br>
<br>
  <syntaxhighlight lang="mysql">
  <syntaxhighlight lang="mysql">
  SELECT '100' + 50;
-- 偶数・奇数の判定
  -- 結果: 150 (文字列 '100' が数値 100 に変換される)
  SELECT id, id % 2 AS is_odd FROM users;
  -- is_odd=0: 偶数、is_odd=1: 奇数
   
   
  SELECT CONCAT(123, ' items');
-- 3件ごとにグループ分け
-- 結果: '123 items' (数値 123 が文字列 '123' に変換される)
  SELECT id, id % 3 AS group_no FROM items;
   
   
  SELECT * FROM users WHERE user_id = '42';
-- 曜日計算 (0=日曜, 6=土曜)
-- user_idが整数型の場合、文字列 '42' が数値 42 に変換される
  SELECT DAYOFWEEK(order_date) % 7 AS weekday FROM orders;
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
==== 文字列から数値への暗黙変換 ====
==== 演算精度と型の規則 ====
文字列が数値として解釈される場合、MySQLは文字列の先頭から数値として読み取れる部分までを変換する。<br>
MySQLの算術演算では、オペランドのデータ型に応じて結果の型が決定される。<br>
<br>
<br>
変換ルールを以下に示す。<br>
型推論の規則を以下に示す。<br>
<br>
<br>
<center>
<center>
{| class="wikitable"
{| class="wikitable"
|+ 文字列から数値への変換規則
|+ 算術演算の型推論規則
! オペランド !! 結果型 !! 説明
|-
|-
! 条件 !! 説明
| 整数 + 整数 || BIGINT || 64ビット整数精度
|-
|-
| 先頭が数字の場合 || 数値として読み取れる部分まで変換
| DECIMAL + 整数 || DECIMAL || 固定小数点精度を保持
|-
|-
| 先頭が数字でない場合 || 0に変換
| DECIMAL + DECIMAL || DECIMAL || より高い精度を採用
|-
|-
| 指数表記 (科学的表記法) をサポート || <code>1.5e2</code> は 150 に変換
| FLOAT/DOUBLE + 任意 || DOUBLE || 浮動小数点精度
|-
|-
| カンマ区切りは数値として認識されない || <code>1,234,567</code> は 1 に変換 (カンマで終了)
| 整数 / 整数 || DECIMAL || 除算結果は小数を含む可能性
|}
|}
</center>
</center>
<br>
<br>
文字列から数値への変換例を以下に示す。<br>
型推論の例を以下に示す。<br>
<br>
<u>このルールにより、予期しない結果が生じる可能性がある。</u><br>
<u>例えば、<code>'1,234,567'</code> という文字列は、1に変換される。</u><br>
<br>
<br>
  <syntaxhighlight lang="mysql">
  <syntaxhighlight lang="mysql">
  SELECT '123' + 0;
  SELECT 10 + 20;
  -- 結果: 123
  -- 結果型: BIGINT
   
   
  SELECT '123abc' + 0;
  SELECT 10.5 + 20;
  -- 結果: 123 (先頭の数値部分のみ変換)
  -- 結果型: DECIMAL
   
   
  SELECT 'abc123' + 0;
  SELECT 10.5 + 20.3;
  -- 結果: 0 (先頭が数字でないため0に変換)
  -- 結果型: DECIMAL
   
   
  SELECT '1.5e2' + 0;
  SELECT 10.5E0 + 20;
  -- 結果: 150 (指数表記を解釈)
  -- 結果型: DOUBLE (科学記法を使用した場合は浮動小数点)
   
   
  SELECT '1,234,567' + 0;
  SELECT 3 / 2;
  -- 結果: 1 (カンマで数値部分が終了)
  -- 結果: 1.5000 (DECIMAL型)
   
   
  SELECT '  456  ' + 0;
  SELECT CAST(3 AS DECIMAL) / CAST(2 AS DECIMAL);
  -- 結果: 456 (前後の空白は無視)
  -- 結果: 1.5000
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
==== 数値から文字列への暗黙変換 ====
整数オーバーフローの動作を以下に示す。<br>
数値が文字列として解釈される場面では、MySQLは数値を文字列に自動変換する。<br>
<br>
数値から文字列への変換は、比較的直感的である。<br>
<br>
<br>
文字列コンテキストの例を以下に示す。<br>
<u>オーバーフロー動作は、<code>sql_mode</code> 設定により変化する。</u><br>
<u>デフォルトでは、オーバーフロー時にエラーが発生する。</u><br>
<br>
<br>
  <syntaxhighlight lang="mysql">
  <syntaxhighlight lang="mysql">
SELECT CONCAT(2, ' items');
  -- BIGINT範囲: -9223372036854775808 ~ 9223372036854775807
  -- 結果: '2 items' (数値 2 が文字列 '2' に変換)
   
   
  SELECT CONCAT(123.45, ' dollars');
  SELECT 9223372036854775807 + 1;
  -- 結果: '123.45 dollars'
  -- ERROR: BIGINT value is out of range (sql_modeによる)
   
   
  SELECT CONCAT(NULL, ' test');
  -- オーバーフロー許容モード (NO_UNSIGNED_SUBTRACTION無効)
  -- 結果: NULL
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 ====
MySQLは、日付型の文字列表現を"緩やかな"フォーマットで受け入れる。<br>
<code>ROUND</code> 関数は、数値を指定された桁数に丸める。<br>
<br>
<br>
日付型の暗黙変換の特徴を以下に示す。<br>
基本構文を以下に示す。<br>
<br>
<syntaxhighlight lang="mysql">
ROUND(x)
ROUND(x, d)
</syntaxhighlight>
<br>
<br>
<center>
<center>
{| class="wikitable"
{| class="wikitable"
|+ 文字列から日付/時刻への変換規則
|+ 引数の意味
|-
|-
! 規則 !! 説明
! 引数 !! 説明
|-
| 区切り文字の柔軟性 || <code>-</code>、<code>/</code>、<code>#</code> 等の区切り文字を使用可能
|-
|-
| 区切り文字なしの形式 || <code>20240815</code> のような形式も認識
| 第1引数 || 対象数値
|-
|-
| 時刻部分のオプション || 日付のみ、または日付と時刻の両方を指定可能
| 第2引数 || 小数点以下の桁数 (省略時は0)。負の値を指定すると小数点より左側を丸める
|}
|}
</center>
</center>
<br>
<br>
日付型の暗黙変換の例を以下に示す。<br>
丸め方式は、数値型により異なる。<br>
* 正確値型 (DECIMAL)
*: round half away from zero (四捨五入)
* 近似値型 (FLOAT, DOUBLE)
*: 実装依存 (銀行家の丸め/偶数丸めになる場合がある)
<br>
<br>
<u>ただし、日本語の日付表記 (例: <code>2024年8月15日</code>) は認識されない。</u><br>
使用例を以下に示す。<br>
<u>このような形式の日付を変換する場合は、<code>STR_TO_DATE</code> 関数を使用する。</u><br>
<br>
<br>
  <syntaxhighlight lang="mysql">
  <syntaxhighlight lang="mysql">
  SELECT CAST('2024-08-15' AS DATE);
  SELECT ROUND(2.5);
  -- 結果: 2024-08-15
-- 結果: 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 CAST('2024/08/15' AS DATE);
  SELECT ROUND(2.55E0, 1);
  -- 結果: 2024-08-15 (区切り文字 / を認識)
  -- 結果: 2.5 (近似値型で偶数丸めになる可能性)
</syntaxhighlight>
<br>
負の桁数指定により、整数部分の丸めが可能である。<br>
<br>
浮動小数点型と正確値型の丸め動作の違いを以下に示す。<br>
<br>
<u>金額計算等の精度が重要な処理では、DECIMAL型の使用を推奨する。</u><br>
<br>
<syntaxhighlight lang="mysql">
-- 正確値型 (DECIMAL)
SELECT ROUND(2.5);
-- 結果: 3
   
   
  SELECT CAST('2024#08#15' AS DATE);
  SELECT ROUND(3.5);
  -- 結果: 2024-08-15 (区切り文字 # を認識)
  -- 結果: 4
   
   
  SELECT CAST('20240815' AS DATE);
-- 近似値型 (DOUBLE)
  -- 結果: 2024-08-15 (区切り文字なしも認識)
  SELECT ROUND(2.5E0);
  -- 結果: 2 (偶数丸めの可能性)
   
   
  SELECT CAST('2024-08-15 14:30:00' AS DATETIME);
  SELECT ROUND(3.5E0);
  -- 結果: 2024-08-15 14:30:00
  -- 結果: 4
  </syntaxhighlight>
  </syntaxhighlight>
<br><br>
== 比較時の型変換ルール ==
MySQLは、異なる型の値を比較する際に、一定のルールに従って型変換を実行する。<br>
<br>
<br>
==== 型変換の優先順位 ====
==== TRUNCATE ====
MySQLは、以下に示す優先順位で型変換を実行する。<br>
<code>TRUNCATE</code> 関数は、小数部を切り捨てる。(0方向に切り捨て)<br>
<br>
基本構文を以下に示す。<br>
<br>
<syntaxhighlight lang="mysql">
TRUNCATE(x, d)
</syntaxhighlight>
<br>
<br>
<center>
<center>
{| class="wikitable"
{| class="wikitable"
|+ 型変換の優先順位
|+ 引数の意味
|-
|-
! 優先順位 !! 条件 !! 変換規則
! 引数 !! 説明
|-
| 1 || NULLの場合 || 結果は <code>NULL</code> (<code>&lt;=&gt;</code> 演算子は例外)
|-
| 2 || 両方が文字列の場合 || 文字列として比較
|-
| 3 || 両方が整数の場合 || 整数として比較
|-
|-
| 4 || DECIMALが含まれる場合 || DECIMAL精度ルールに従って比較
| 第1引数 || 対象数値
|-
|-
| 5 || その他の場合 || 浮動小数点数として比較
| 第2引数 || 小数点以下の桁数。負の値を指定すると小数点より左側を0にする
|}
|}
</center>
</center>
<br>
<br>
比較時の型変換の例を以下に示す。<br>
使用例を以下に示す。<br>
<br>
<br>
  <syntaxhighlight lang="mysql">
  <syntaxhighlight lang="mysql">
  SELECT 1 = '1';
  SELECT TRUNCATE(1.999, 1);
  -- 結果: 1 (true) (文字列 '1' が数値 1 に変換)
  -- 結果: 1.9 (小数第2位以降を切り捨て)
SELECT TRUNCATE(1.999, 0);
-- 結果: 1 (小数部を切り捨て)
   
   
  SELECT 0 = 'abc';
  SELECT TRUNCATE(1.999, 2);
  -- 結果: 1 (true) (文字列 'abc' が数値 0 に変換)
  -- 結果: 1.99
   
   
  SELECT 1 = 1.0;
  SELECT TRUNCATE(-1.999, 1);
  -- 結果: 1 (true) (整数と浮動小数点の比較)
  -- 結果: -1.9 (0方向に切り捨て)
   
   
  SELECT 'abc' = 'ABC';
  SELECT TRUNCATE(122, -2);
  -- 結果: 1 (true) (デフォルトの照合順序は大文字小文字を区別しない)
-- 結果: 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 ====
文字列と数値を比較する場合、<u>文字列が数値に変換</u> される。<br>
<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>
<br>
この動作により、予期しない比較結果が生じる可能性がある。<br>
<code>CEIL</code> 関数は、切り上げ処理に相当する。<br>
特に、<u>'abc' = 0 が true</u> となる点に注意すること。<br>
ただし、負数では動作が異なるため注意が必要である。<br>
<br>
<br>
  <syntaxhighlight lang="mysql">
  <syntaxhighlight lang="mysql">
  SELECT 1 > '6x';
  SELECT CEIL(1.23);
  -- 結果: 0 (false) ('6x' は 6 に変換、1 > 6 は false)
  -- 結果: 2
SELECT CEILING(1.23);
-- 結果: 2
   
   
  SELECT 7 > '6x';
  SELECT CEIL(-1.23);
  -- 結果: 1 (true) ('6x' は 6 に変換、7 > 6 は true)
  -- 結果: -1 (-1.23以上の最小の整数は-1)
   
   
  SELECT 0 = 'x6';
  SELECT CEIL(5);
  -- 結果: 1 (true) ('x6' は 0 に変換、0 = 0 は true)
  -- 結果: 5 (整数の場合はそのまま)
   
   
  SELECT 'abc' = 0;
  SELECT CEIL(1.01);
  -- 結果: 1 (true) ('abc' は 0 に変換)
  -- 結果: 2
   
   
  SELECT '123' > 99;
  SELECT CEIL(-1.01);
  -- 結果: 1 (true) ('123' は 123 に変換、123 > 99 は true)
  -- 結果: -1
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
==== 照合順序と比較 ====
==== FLOOR ====
文字列同士の比較では、照合順序 (Collation) が比較結果に影響する。<br>
<code>FLOOR</code> 関数は、x以下の最大の整数を返す。<br>
<br>
<br>
大文字小文字を区別する比較を行う場合は、<code>BINARY</code> 演算子 または <code>COLLATE utf8mb4_bin</code> を使用する。<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 'abc' = 'ABC';
  SELECT FLOOR(1.23);
  -- 結果: 1 (true) (デフォルトの照合順序は大文字小文字を区別しない)
  -- 結果: 1
   
   
  SELECT 'abc' = 'ABC' COLLATE utf8mb4_bin;
  SELECT FLOOR(-1.23);
  -- 結果: 0 (false) (バイナリ比較では区別)
  -- 結果: -2 (-1.23以下の最大の整数は-2)
   
   
  SELECT BINARY 'abc' = 'ABC';
  SELECT FLOOR(5);
  -- 結果: 0 (false) (BINARY演算子でバイナリ比較を強制)
-- 結果: 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>


== 明示的な型変換 ==
== 絶対値・符号関数 ==
明示的な型変換は、<code>CAST</code> 関数 または <code>CONVERT</code> 関数を使用して実行する。<br>
==== ABS ====
これらの関数により、ユーザが意図した型変換を明確に指定できる。<br>
<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>
==== CAST関数 ====
==== SIGN ====
<code>CAST</code> 関数は、SQL標準の型変換関数である。<br>
<code>SIGN</code> 関数は、数値の符号を返す。<br>
<br>
<br>
基本構文を以下に示す。<br>
基本構文を以下に示す。<br>
<br>
<br>
  <syntaxhighlight lang="mysql">
  <syntaxhighlight lang="mysql">
  CAST(expr AS type [ARRAY])
  SIGN(x)
  </syntaxhighlight>
  </syntaxhighlight>
<br>
戻り値を以下に示す。<br>
<br>
<br>
<center>
<center>
{| class="wikitable"
{| class="wikitable"
|+ <code>CAST</code>関数の引数
|+ <code>SIGN</code> 関数の戻り値
! 引数 !! 説明
|-
! 引数 !! 戻り値
|-
|-
| <code>expr</code> || 変換する値または式
| 負数 || -1
|-
|-
| <code>type</code> || 変換先の型
| 0 || 0
|-
|-
| <code>ARRAY</code> || JSON配列への変換 (オプション、MySQL 8.0.17以降)
| 正数 || 1
|}
|}
</center>
</center>
<br>
<br>
<code>CAST</code> 関数の使用例を以下に示す。<br>
使用例を以下に示す。<br>
<br>
<br>
  <syntaxhighlight lang="mysql">
  <syntaxhighlight lang="mysql">
  SELECT CAST('123' AS SIGNED);
  SELECT SIGN(-32);
  -- 結果: 123 (文字列を符号付き整数に変換)
-- 結果: -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 CAST(123.456 AS DECIMAL(5,2));
  SELECT POW(10, 2);
  -- 結果: 123.46 (浮動小数点数を固定小数点数に変換、四捨五入)
  -- 結果: 100
   
   
  SELECT CAST('2024-08-15' AS DATE);
  SELECT POW(2, 0);
  -- 結果: 2024-08-15 (文字列を日付型に変換)
  -- 結果: 1 (任意の数の0乗は1)
   
   
  SELECT CAST('2024-08-15 14:30:00' AS DATETIME);
  SELECT POW(2, 0.5);
  -- 結果: 2024-08-15 14:30:00 (文字列を日時型に変換)
  -- 結果: 1.4142135623730951 (2の平方根)
   
   
  SELECT CAST(123 AS CHAR);
  SELECT POW(4, 0.5);
  -- 結果: '123' (数値を文字列に変換)
  -- 結果: 2
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
==== CONVERT関数 ====
<u>負の指数を指定することで、逆数の計算が可能である。</u><br>
<code>CONVERT</code> 関数は、MySQL独自の型変換関数である。<br>
<br>
<code>CONVERT</code> 関数には、2つの構文が存在する。<br>
実用例を以下に示す。<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">
  CONVERT(expr, type)
  SQRT(x)
CONVERT(expr USING transcoding_name)
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
<center>
負の値を指定した場合はNULLを返す。<br>
{| class="wikitable"
|+ <code>CONVERT</code>関数の構文
! 構文 !! 説明
|-
| <code>CONVERT(expr, type)</code> || <code>CAST</code>関数と同様の型変換
|-
| <code>CONVERT(expr USING transcoding_name)</code> || 文字セット変換
|}
</center>
<br>
<br>
<code>CONVERT</code> 関数の使用例を以下に示す。<br>
使用例を以下に示す。<br>
<br>
<br>
  <syntaxhighlight lang="mysql">
  <syntaxhighlight lang="mysql">
  SELECT CONVERT('123', SIGNED);
  SELECT SQRT(4);
  -- 結果: 123
  -- 結果: 2
SELECT SQRT(20);
-- 結果: 4.47213595499958
SELECT SQRT(2);
-- 結果: 1.4142135623730951
SELECT SQRT(0);
-- 結果: 0
   
   
  SELECT CONVERT(123.456, DECIMAL(5,2));
  SELECT SQRT(-16);
  -- 結果: 123.46
  -- 結果: NULL (負数の平方根はNULL)
   
   
  SELECT CONVERT('Hello' USING utf8mb4);
  SELECT SQRT(NULL);
  -- 結果: 'Hello' (文字セットをutf8mb4に変換)
  -- 結果: NULL
</syntaxhighlight>
<br>
実用例を以下に示す。<br>
<br>
<syntaxhighlight lang="mysql">
-- 2点間の距離を計算 (ピタゴラスの定理)
SELECT SQRT(POW(x2 - x1, 2) + POW(y2 - y1, 2)) AS distance
FROM points;
   
   
  SELECT CONVERT('データ' USING latin1);
-- 標準偏差の計算
  -- エラーまたは文字化け (latin1は日本語をサポートしない)
  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>
文字セット指定付き <code>CAST</code> 関数の構文を以下に示す。<br>
使用例を以下に示す。<br>
<br>
<br>
  <syntaxhighlight lang="mysql">
  <syntaxhighlight lang="mysql">
  CAST(expr AS CHAR CHARACTER SET charset_name)
  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>
文字セット指定の例を以下に示す。<br>
<code>EXP</code> 関数は、自然対数関数 <code>LN</code> の逆関数である。<br>
<br>
<br>
  <syntaxhighlight lang="mysql">
  <syntaxhighlight lang="mysql">
  SELECT CAST('Hello' AS CHAR CHARACTER SET utf8mb4);
  SELECT EXP(LN(10));
  -- 結果: 'Hello'
  -- 結果: 10
   
   
  SELECT CAST('データベース' AS CHAR CHARACTER SET utf8mb4);
  SELECT LN(EXP(5));
  -- 結果: 'データベース'
  -- 結果: 5
  </syntaxhighlight>
  </syntaxhighlight>
<br><br>
== 対数関数 ==
対数関数は、指数の逆演算を実行する。<br>
MySQLでは、自然対数、常用対数、任意の底の対数を計算できる。<br>
<br>
<br>
==== CAST / CONVERTで使用可能な型の詳細 ====
==== LN / LOG ====
<code>CAST</code> 関数 および <code>CONVERT</code> 関数では、以下に示す型への変換がサポートされている。<br>
<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"
|+ サポートされる型の一覧
|+ 引数の意味
! 型 !! 説明 !! 追加されたバージョン
|-
|-
| <code>BINARY[(N)]</code> || バイナリ文字列型 ||
! 関数形式 !! 説明
|-
|-
| <code>CHAR[(N)]</code> || 固定長文字列型 ||
| LN(x) || xの自然対数 (底e)
|-
|-
| <code>DATE</code> || 日付型 ||
| LOG(x) || xの自然対数 (LN(x)と同じ)
|-
|-
| <code>DATETIME</code> || 日時型 ||
| LOG(b, x) || 底bに対するxの対数
|-
| <code>TIME</code> || 時刻型 ||
|-
| <code>DECIMAL[(M[,D])]</code> || 固定小数点型 ||
|-
| <code>SIGNED [INTEGER]</code> || 符号付き整数型 ||
|-
| <code>UNSIGNED [INTEGER]</code> || 符号なし整数型 ||
|-
| <code>FLOAT[(p)]</code> || 単精度浮動小数点型 || MySQL 8.0.17以降
|-
| <code>DOUBLE</code> || 倍精度浮動小数点型 || MySQL 8.0.17以降
|-
| <code>REAL</code> || REAL型 (FLOATまたはDOUBLE) || MySQL 8.0.17以降
|-
| <code>JSON</code> || JSON型 ||
|-
| <code>YEAR</code> || 年型 || MySQL 8.0.22以降
|-
| 空間型 || Point、LineString等 || MySQL 8.0.24以降
|}
|}
</center>
</center>
<br>
<br>
===== BINARY / CHAR =====
<math>x \le 0</math> の場合は、<code>NULL</code> を返す。<br>
<code>BINARY</code> 型 および <code>CHAR</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>BINARY[(N)]</code> の場合、<code>N</code> はバイト数を指定する。<br>
==== LOG2 ====
<code>CHAR[(N)]</code> の場合、<code>N</code> は文字数ではなくバイト数を指定する点に注意すること。<br>
<code>LOG2</code> 関数は、底2の対数を返す。<br>
<br>
基本構文を以下に示す。<br>
<br>
<br>
  <syntaxhighlight lang="mysql">
  <syntaxhighlight lang="mysql">
  SELECT CAST(123 AS CHAR);
LOG2(x)
  -- 結果: '123'
</syntaxhighlight>
<br>
使用例を以下に示す。<br>
<br>
<syntaxhighlight lang="mysql">
SELECT LOG2(65536);
-- 結果: 16 (2^16 = 65536)
SELECT LOG2(256);
-- 結果: 8
  SELECT LOG2(2);
  -- 結果: 1
   
   
  SELECT CAST('Hello' AS BINARY(10));
  SELECT LOG2(1);
  -- 結果: 'Hello\0\0\0\0\0' (10バイトに拡張、NULLバイトでパディング)
  -- 結果: 0
   
   
  SELECT CAST('Hello World' AS CHAR(5));
  SELECT LOG2(1024);
  -- 結果: 'Hello' (5バイトに切り詰め)
  -- 結果: 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 ====
数値型への変換には、整数型、固定小数点型、浮動小数点型が含まれる。<br>
<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"
|+ 数値型への変換
|+ 基本三角関数
! !! 説明
! 関数 !! 説明 !! 使用例 !! 結果
|-
|-
| <code>SIGNED [INTEGER]</code> || 符号付き整数型 (-9223372036854775808 ~ 9223372036854775807)
| SIN(x) || 正弦 (サイン) || SELECT SIN(PI()/2) || 1
|-
|-
| <code>UNSIGNED [INTEGER]</code> || 符号なし整数型 (0 ~ 18446744073709551615)
| COS(x) || 余弦 (コサイン) || SELECT COS(PI()) || -1
|-
|-
| <code>DECIMAL[(M[,D])]</code> || 固定小数点型 (M: 精度、D: 小数点以下桁数)
| TAN(x) || 正接 (タンジェント) || SELECT TAN(PI()/4) || 1
|-
|-
| <code>FLOAT[(p)]</code> || 単精度浮動小数点型 (p: 精度 0-53)
| COT(x) || 余接 (コタンジェント) || SELECT COT(PI()/4) || 1
|-
| <code>DOUBLE</code> || 倍精度浮動小数点型
|-
| <code>REAL</code> || REAL型 (REAL_AS_FLOATモード設定時はFLOAT、それ以外はDOUBLE)
|}
|}
</center>
</center>
<br>
<br>
<code>FLOAT[(p)]</code> の精度指定について以下に示す。<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"
|+ <code>FLOAT[(p)]</code> の精度指定
|+ 逆三角関数
! 関数 !! 説明 !! 定義域 !! 値域
|-
|-
! 精度 <code>p</code> の範囲 !! 変換先
| ASIN(x) || 逆正弦 (アークサイン) || -1 ≤ x ≤ 1 || -π/2 ~ π/2
|-
|-
| 0〜24 || <code>FLOAT</code> 型 (単精度浮動小数点)
| ACOS(x) || 逆余弦 (アークコサイン) || -1 ≤ x ≤ 1 || 0 ~ π
|-
|-
| 25〜53 || <code>DOUBLE</code> 型 (倍精度浮動小数点)
| ATAN(x) || 逆正接 (アークタンジェント) || 全ての実数 || -π/2 ~ π/2
|-
| ATAN2(y, x) || 2引数逆正接 || 全ての実数 || -π ~ π
|}
|}
</center>
</center>
<br>
<br>
数値型への変換の例を以下に示す。<br>
使用例を以下に示す。<br>
<br>
<br>
  <syntaxhighlight lang="mysql">
  <syntaxhighlight lang="mysql">
  SELECT CAST('123' AS SIGNED);
  SELECT ASIN(1);
  -- 結果: 123
  -- 結果: 1.5707963267948966 (π/2、90度)
SELECT ACOS(-1);
-- 結果: 3.141592653589793 (π、180度)
   
   
  SELECT CAST('-456' AS SIGNED);
  SELECT ATAN(1);
  -- 結果: -456
  -- 結果: 0.7853981633974483 (π/4、45度)
   
   
  SELECT CAST('789' AS UNSIGNED);
  SELECT ATAN2(1, 1);
  -- 結果: 789
  -- 結果: 0.7853981633974483 (π/4、45度)
   
   
  SELECT CAST('-123' AS UNSIGNED);
  SELECT ASIN(2);
  -- 結果: 18446744073709551493 (オーバーフロー)
  -- 結果: NULL (定義域外)
   
   
  SELECT CAST(123.456 AS DECIMAL(5,2));
  SELECT ASIN(-1);
  -- 結果: 123.46 (四捨五入)
-- 結果: -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 CAST('123.456' AS FLOAT);
  SELECT ATAN2(0, 1);
  -- 結果: 123.456
  -- 結果: 0 (x軸正方向)
   
   
  SELECT CAST('123.456' AS DOUBLE);
  SELECT ATAN2(-1, 0);
  -- 結果: 123.456
  -- 結果: -1.5707963267948966 (-π/2、-90度、y軸負方向)
   
   
  SELECT CAST('1.23e2' AS DOUBLE);
  SELECT ATAN2(0, -1);
  -- 結果: 123 (指数表記を解釈)
  -- 結果: 3.141592653589793 (π、180度、x軸負方向)
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
===== 日付・時刻型 =====
==== 角度変換 ====
日付型および時刻型への変換には、以下に示す型が含まれる。<br>
角度変換関数により、ラジアンと度の相互変換が可能である。<br>
<br>
<br>
<center>
<center>
{| class="wikitable"
{| class="wikitable"
|+ 日付・時刻型への変換
|+ 角度変換関数
! !! 形式 !! 説明
! 関数 !! 説明 !! 使用例 !! 結果
|-
| <code>DATE</code> || YYYY-MM-DD || 日付型
|-
| <code>TIME</code> || HH:MM:SS || 時刻型
|-
|-
| <code>DATETIME</code> || YYYY-MM-DD HH:MM:SS || 日時型
| DEGREES(x) || ラジアン → 度 || SELECT DEGREES(PI()) || 180
|-
|-
| <code>YEAR</code> || YYYY || 年型 (MySQL 8.0.22以降)
| RADIANS(x) || 度 → ラジアン || SELECT RADIANS(180) || 3.141592653589793
|}
|}
</center>
</center>
<br>
<br>
日付・時刻型への変換の例を以下に示す。<br>
使用例を以下に示す。<br>
<br>
<br>
  <syntaxhighlight lang="mysql">
  <syntaxhighlight lang="mysql">
  SELECT CAST('2024-08-15' AS DATE);
  SELECT DEGREES(PI());
  -- 結果: 2024-08-15
-- 結果: 180
SELECT DEGREES(PI()/2);
  -- 結果: 90
   
   
  SELECT CAST('14:30:00' AS TIME);
  SELECT RADIANS(180);
  -- 結果: 14:30:00
  -- 結果: 3.141592653589793 (π)
   
   
  SELECT CAST('2024-08-15 14:30:00' AS DATETIME);
  SELECT RADIANS(90);
  -- 結果: 2024-08-15 14:30:00
  -- 結果: 1.5707963267948966 (π/2)
   
   
  SELECT CAST('2024' AS YEAR);
  SELECT RADIANS(360);
  -- 結果: 2024 (MySQL 8.0.22以降)
  -- 結果: 6.283185307179586 (2π)
</syntaxhighlight>
<br>
度単位での三角関数計算例を以下に示す。<br>
<br>
<syntaxhighlight lang="mysql">
SELECT SIN(RADIANS(30));
-- 結果: 0.49999999999999994 (約0.5、30度のサイン)
   
   
  SELECT CAST('2024-08-15 14:30:00' AS DATE);
  SELECT COS(RADIANS(60));
  -- 結果: 2024-08-15 (時刻部分は切り捨て)
  -- 結果: 0.5000000000000001 (約0.5、60度のコサイン)
   
   
  SELECT CAST('2024-08-15 14:30:00' AS TIME);
  SELECT DEGREES(ASIN(0.5));
  -- 結果: 14:30:00 (日付部分は切り捨て)
  -- 結果: 30.000000000000004 (約30度)
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
<code>AT TIME ZONE</code> 演算子による時刻変換 (MySQL 8.0.22以降) を以下に示す。<br>
==== PI ====
<code>PI</code> 関数は、円周率πの値を返す。<br>
<br>
基本構文を以下に示す。<br>
<br>
<br>
  <syntaxhighlight lang="mysql">
  <syntaxhighlight lang="mysql">
  SELECT CAST('2024-08-15 14:30:00' AS DATETIME) AT TIME ZONE '+00:00';
  PI()
-- 結果: UTCタイムゾーンに変換
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
===== JSON =====
使用例を以下に示す。<br>
<code>JSON</code> 型への変換は、文字列、数値、オブジェクト、配列をJSON形式に変換する。<br>
<br>
<br>
  <syntaxhighlight lang="mysql">
  <syntaxhighlight lang="mysql">
  SELECT CAST('{}' AS JSON);
  SELECT PI();
  -- 結果: {} (空のJSONオブジェクト)
  -- 結果: 3.141593 (表示精度は倍精度)
   
   
  SELECT CAST('[1,2,3]' AS JSON);
  SELECT PI() * 2;
  -- 結果: [1,2,3] (JSON配列)
  -- 結果: 6.283185307179586 ()
   
   
  SELECT CAST(123 AS JSON);
  SELECT PI() / 2;
  -- 結果: 123 (JSON数値)
  -- 結果: 1.5707963267948966 (π/2)
   
   
  SELECT CAST('"Hello"' AS JSON);
  -- 円の面積計算 (πr^2)
  -- 結果: "Hello" (JSON文字列)
  SELECT PI() * POW(radius, 2) AS area FROM circles;
   
   
  SELECT CAST('{"name":"Alice","age":30}' AS JSON);
  -- 円周計算 (2πr)
  -- 結果: {"name":"Alice","age":30} (JSONオブジェクト)
  SELECT 2 * PI() * radius AS circumference FROM circles;
  </syntaxhighlight>
  </syntaxhighlight>
<br><br>
<br><br>


== JSON関連の型変換 ==
== ランダム関数 ==
MySQL 8.0では、JSON型と他の型の間での変換が強化されている。<br>
MySQLでは、乱数生成関数が提供されている。<br>
<br>
==== RAND ====
<code>RAND</code> 関数は、0以上1未満の乱数を返す。<br>
戻り値の型は、<code>DOUBLE</code> である。<br>
<br>
<br>
==== JSON型への変換 ====
基本構文を以下に示す。<br>
JSON型への変換は、<code>CAST</code> 関数を使用して実行する。<br>
<br>
<br>
  <syntaxhighlight lang="mysql">
  <syntaxhighlight lang="mysql">
  SELECT CAST('{"name":"Alice"}' AS JSON);
  RAND()
  -- 結果: {"name":"Alice"}
RAND(seed)
</syntaxhighlight>
<br>
<center>
{| class="wikitable"
|+ 引数の意味
|-
! 形式 !! 説明
|-
| RAND() || ランダムな乱数を生成
|-
| RAND(seed) || シード値を指定して再現可能な乱数列を生成
|}
</center>
<br>
使用例を以下に示す。<br>
<br>
<syntaxhighlight lang="mysql">
SELECT RAND();
  -- 結果: 0.6912345678901234 (実行ごとに異なる)
   
   
  SELECT CAST('[1,2,3,4,5]' AS JSON);
  SELECT RAND();
  -- 結果: [1,2,3,4,5]
  -- 結果: 0.1234567890123456 (毎回異なる値)
   
   
  SELECT CAST(123 AS JSON);
  SELECT RAND(100);
  -- 結果: 123
  -- 結果: 0.9546361446761204 (シード100の場合は常に同じ値)
   
   
  SELECT CAST(true AS JSON);
  SELECT RAND(100);
  -- 結果: true
  -- 結果: 0.9546361446761204 (シードが同じなら同じ値)
   
   
  SELECT CAST(NULL AS JSON);
  SELECT RAND(200);
  -- 結果: null (JSONのnull値)
  -- 結果: 0.44880484265643147 (異なるシード)
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
==== JSON型からの変換 ====
シード値を指定することで、再現可能な乱数列を生成できる。<br>
JSON型から他の型への変換には、<code>JSON_UNQUOTE</code> 関数 と <code>JSON_EXTRACT</code> 関数を組み合わせる方法がある。<br>
これは、テストデータ生成時に有用である。<br>
<br>
整数範囲の乱数を生成する例を以下に示す。<br>
<br>
<br>
  <syntaxhighlight lang="mysql">
  <syntaxhighlight lang="mysql">
  SET @json = '{"name":"Alice","age":30}';
  -- 1~6のランダム整数 (サイコロ)
SELECT FLOOR(RAND() * 6) + 1;
   
   
  SELECT JSON_EXTRACT(@json, '$.name');
-- 0~99のランダム整数
-- 結果: "Alice" (JSON文字列、ダブルクォート付き)
  SELECT FLOOR(RAND() * 100);
   
   
  SELECT JSON_UNQUOTE(JSON_EXTRACT(@json, '$.name'));
-- min~maxのランダム整数
-- 結果: Alice (ダブルクォートを除去)
  SELECT FLOOR(RAND() * (max - min + 1)) + min;
   
   
  SELECT CAST(JSON_EXTRACT(@json, '$.age') AS SIGNED);
-- 10~20のランダム整数
-- 結果: 30 (数値に変換)
  SELECT FLOOR(RAND() * 11) + 10;
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
MySQL 8.0.21以降では、<code>JSON_VALUE</code> 関数が利用可能である。<br>
ランダムにレコードを取得する例を以下に示す。<br>
<br>
<br>
<code>JSON_VALUE</code> 関数の構文を以下に示す。<br>
<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">
  JSON_VALUE(json_doc, path [RETURNING type] [on_empty] [on_error])
  -- 代替手法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"
|+ <code>JSON_VALUE</code>関数の引数
|+ ビット演算子
! 引数 !! 説明
! 演算子 !! 説明 !! 使用例 !! 結果
|-
| & || ビットAND || SELECT 29 & 15 || 13
|-
|-
| <code>json_doc</code> || JSON文書
| <nowiki>|</nowiki> || ビットOR || SELECT 29 <nowiki>|</nowiki> 15 || 31
|-
|-
| <code>path</code> || JSONパス式
| ^ || ビットXOR (排他的論理和) || SELECT 29 ^ 15 || 18
|-
|-
| <code>RETURNING type</code> || 戻り型 (オプション、デフォルト: VARCHAR(512))
| ~ || ビットNOT (反転) || SELECT ~0 || 18446744073709551615
|-
|-
| <code>on_empty</code> || 値が存在しない場合の動作
| << || 左シフト || SELECT 1 << 4 || 16
|-
|-
| <code>on_error</code> || エラー発生時の動作
| >> || 右シフト || SELECT 16 >> 2 || 4
|}
|}
</center>
</center>
<br>
<br>
<code>JSON_VALUE</code> 関数で使用可能な型を以下に示す。<br>
下表に、戻り値を示す。<br>
<br>
<br>
<center>
<center>
{| class="wikitable"
{| class="wikitable"
|+ JSON_VALUE関数で使用可能な型
|+ <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"
|+ 引数の意味
|-
|-
| 数値型 || <code>FLOAT</code>、<code>DOUBLE</code>、<code>DECIMAL</code>、<code>SIGNED</code>、<code>UNSIGNED</code>
! 引数 !! 説明
|-
|-
| 日付・時刻型 || <code>DATE</code>、<code>TIME</code>、<code>DATETIME</code>、<code>YEAR</code>
| 第1引数 || 対象数値
|-
|-
| 文字列型 || <code>CHAR</code>
| 第2引数 || 小数点以下の桁数
|-
|-
| その他 || <code>JSON</code>
| 第3引数 || ロケール (省略時は en_US)
|}
|}
</center>
</center>
<br>
<br>
<code>JSON_VALUE</code> 関数の使用例を以下に示す。<br>
使用例を以下に示す。<br>
<br>
<br>
  <syntaxhighlight lang="mysql">
  <syntaxhighlight lang="mysql">
SET @json = '{"name":"Alice","age":30,"salary":50000.50}';
  SELECT FORMAT(12332.123456, 4);
  -- 結果: '12,332.1235' (小数第5位を四捨五入)
  SELECT JSON_VALUE(@json, '$.name');
  -- 結果: 'Alice' (デフォルトはVARCHAR(512))
   
   
  SELECT JSON_VALUE(@json, '$.age' RETURNING SIGNED);
  SELECT FORMAT(12332.1, 4);
  -- 結果: 30 (符号付き整数に変換)
  -- 結果: '12,332.1000' (小数点以下を0でパディング)
   
   
  SELECT JSON_VALUE(@json, '$.salary' RETURNING DECIMAL(10,2));
  SELECT FORMAT(12332.2, 0);
  -- 結果: 50000.50 (固定小数点数に変換)
  -- 結果: '12,332' (整数部のみ)
   
   
  SELECT JSON_VALUE(@json, '$.unknown' RETURNING SIGNED NULL ON EMPTY);
  SELECT FORMAT(1234567.89, 2);
  -- 結果: NULL (値が存在しない場合はNULLを返す)
  -- 結果: '1,234,567.89'
   
   
  SELECT JSON_VALUE(@json, '$.unknown' RETURNING SIGNED DEFAULT 0 ON EMPTY);
  SELECT FORMAT(1234567.89, 2, 'de_DE');
  -- 結果: 0 (値が存在しない場合は0を返す)
  -- 結果: '1.234.567,89' (ドイツ語ロケール)
   
   
  SELECT JSON_VALUE(@json, '$.invalid' RETURNING SIGNED ERROR ON ERROR);
  SELECT FORMAT(12332.2, 2, 'de_DE');
  -- エラー発生 (変換エラー時にエラーを返す)
  -- 結果: '12.332,20'
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
<code>ON EMPTY</code> 句および <code>ON ERROR</code> 句の動作を以下に示す。<br>
ロケールによる表示形式の違いを以下に示す。<br>
<br>
<br>
<center>
<center>
{| class="wikitable"
{| class="wikitable"
|+ ON EMPTY / ON ERROR句の動作
|+ ロケールによる表示形式
! !! 説明
! ロケール !! 千の位区切り !! 小数点記号 !! 例
|-
|-
| <code>NULL ON EMPTY</code> || 値が存在しない場合、NULLを返す (デフォルト)
| en_US || カンマ (,) || ピリオド (.) || 1,234.56
|-
|-
| <code>DEFAULT value ON EMPTY</code> || 値が存在しない場合、指定したデフォルト値を返す
| de_DE || ピリオド (.) || カンマ (,) || 1.234,56
|-
|-
| <code>ERROR ON EMPTY</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"
|+ 引数の意味
|-
! 引数 !! 説明
|-
|-
| <code>NULL ON ERROR</code> || 変換エラー時、NULLを返す (デフォルト)
| 第1引数 || 変換する数値 (文字列または整数)
|-
|-
| <code>DEFAULT value ON ERROR</code> || 変換エラー時、指定したデフォルト値を返す
| 第2引数 || 元の基数 (2~36)
|-
|-
| <code>ERROR ON ERROR</code> || 変換エラー時、エラーを発生
| 第3引数 || 変換先の基数 (2~36)
|}
|}
</center>
</center>
<br>
<br>
<u>※注意</u><br>
使用例を以下に示す。<br>
<u><code>ON EMPTY</code> 句は、<code>ON ERROR</code> 句より前に置く必要がある。</u><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>
==== JSONと他の型の比較 ====
基数変換の実用例を以下に示す。<br>
JSON型と他の型を比較する場合、MySQLは自動的に型変換を実行する。<br>
<br>
<br>
  <syntaxhighlight lang="mysql">
  <syntaxhighlight lang="mysql">
  SET @json = '{"value":123}';
  -- 2進数 → 10進数
SELECT CONV('11111111', 2, 10);
-- 結果: '255'
   
   
  SELECT JSON_EXTRACT(@json, '$.value') = 123;
-- 10進数 → 16進数
  -- 結果: 1 (true) (JSON数値と整数を比較)
  SELECT CONV(255, 10, 16);
  -- 結果: 'FF'
   
   
  SELECT JSON_EXTRACT(@json, '$.value') = '123';
-- 16進数 → 2進数
  -- 結果: 1 (true) (JSON数値と文字列を比較)
  SELECT CONV('FF', 16, 2);
  -- 結果: '11111111'
  </syntaxhighlight>
  </syntaxhighlight>
<br><br>
== 型変換に関する注意点 ==
==== データ損失のリスク ====
型変換により、データが損失または変更される場合がある。<br>
<br>
<br>
データ損失が発生する例を以下に示す。<br>
==== HEX / UNHEX ====
<code>HEX</code> 関数は、数値または文字列を16進数表現に変換する。<br>
<code>UNHEX</code> 関数は、16進数表現をバイナリ文字列に変換する。<br>
<br>
基本構文を以下に示す。<br>
<br>
<br>
* 固定小数点数から整数への変換
<syntaxhighlight lang="mysql">
*: 小数部が切り捨てられる
  HEX(n)
*: <syntaxhighlight lang="mysql">
HEX(str)
  SELECT CAST(123.456 AS SIGNED);
  UNHEX(str)
  -- 結果: 123 (小数部 .456 が切り捨て)
  </syntaxhighlight>
  </syntaxhighlight>
*: <br>
<br>
* 浮動小数点数から固定小数点数への変換
使用例を以下に示す。<br>
*: 丸め誤差が発生する可能性
<br>
*: <syntaxhighlight lang="mysql">
<syntaxhighlight lang="mysql">
  SELECT CAST(123.456789 AS DECIMAL(5,2));
  SELECT HEX(255);
  -- 結果: 123.46 (四捨五入)
-- 結果: '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>
<br>
* 文字列から整数への変換
<code>HEX</code> 関数 と <code>CONV</code> 関数の違いを以下に示す。<br>
*: 数値以外の文字が喪失
<br>
*: <syntaxhighlight lang="mysql">
<syntaxhighlight lang="mysql">
  SELECT CAST('123abc' AS SIGNED);
  SELECT HEX(255);
  -- 結果: 123 ('abc' が喪失)
  -- 結果: 'FF'
   
   
  SELECT CAST('abc123' AS SIGNED);
  SELECT CONV(255, 10, 16);
  -- 結果: 0 (全ての文字が喪失)
  -- 結果: 'FF'
-- 同じ結果だが、HEXは数値→16進数専用、CONVは任意基数変換
  </syntaxhighlight>
  </syntaxhighlight>
*: <br>
<br>
* 日時型から日付型への変換
==== OCT ====
*: 時刻部分が切り捨てられる
<code>OCT</code> 関数は、数値を8進数表現に変換する。<br>
*: <syntaxhighlight lang="mysql">
<br>
  SELECT CAST('2024-08-15 14:30:00' AS DATE);
基本構文を以下に示す。<br>
-- 結果: 2024-08-15 (時刻部分 14:30:00 が切り捨て)
<br>
<syntaxhighlight lang="mysql">
  OCT(n)
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
==== インデックスへの影響 ====
使用例を以下に示す。<br>
WHERE句でカラムに対して型変換を適用すると、インデックスが使用されなくなる。<br>
これにより、クエリのパフォーマンスが大幅に低下する可能性がある。<br>
<br>
<br>
* 良い例
<syntaxhighlight lang="mysql">
*: <syntaxhighlight lang="mysql">
SELECT OCT(12);
  -- 値側で型変換を行う
  -- 結果: '14' (10進数 12 → 8進数)
  SELECT * FROM users WHERE user_id = 123;
  -- インデックスが使用される
  SELECT OCT(8);
-- 結果: '10'
SELECT OCT(255);
  -- 結果: '377'
   
   
-- または、CASTを使わずに比較
  SELECT OCT(0);
  SELECT * FROM users WHERE user_id = CAST('123' AS SIGNED);
  -- 結果: '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">
<br>
  -- user_idが整数型の場合
<syntaxhighlight lang="mysql">
  SELECT * FROM users WHERE CAST(user_id AS CHAR) = '123';
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>
<u>カラムに対して関数または型変換を適用しないことが、インデックスを有効活用するための基本原則である。</u><br>
==== CRC32 ====
<code>CRC32</code> 関数は、CRC32チェックサムを計算する。<br>
戻り値は32ビット符号なし整数である。<br>
<br>
基本構文を以下に示す。<br>
<br>
<br>
==== NULLの扱い ====
<syntaxhighlight lang="mysql">
<code>CAST</code> 関数 および <code>CONVERT</code> 関数は、<code>NULL</code> を変換すると <code>NULL</code> を返す。<br>
CRC32(str)
</syntaxhighlight>
<br>
使用例を以下に示す。<br>
<br>
<br>
  <syntaxhighlight lang="mysql">
  <syntaxhighlight lang="mysql">
  SELECT CAST(NULL AS SIGNED);
  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(NULL AS CHAR);
-- ハッシュベースのパーティショニング
  -- 結果: NULL
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 CAST(NULL AS DATE);
-- 範囲比較を推奨
  -- 結果: NULL
  SELECT * FROM measurements WHERE ABS(value - 0.3) < 0.0001;
  -- 許容誤差内での比較
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
<code>NULL</code> を別の値に置き換える場合は、<code>COALESCE</code> 関数 または <code>IFNULL</code> 関数を使用する。<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 COALESCE(CAST(NULL AS SIGNED), 0);
-- インデックスが使用される
-- 結果: 0
  SELECT * FROM orders WHERE price >= 99.5 AND price < 100.5;
   
   
  SELECT IFNULL(CAST(NULL AS SIGNED), -1);
  -- インデックスが使用される
  -- 結果: -1
  SELECT * FROM products WHERE stock BETWEEN 40 AND 60;
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
==== 文字列と数値の比較でインデックスが使用されない ====
===== 関数ベースインデックス (Generated Column) を使用する例 =====
  <syntaxhighlight lang="mysql">
  <syntaxhighlight lang="mysql">
  -- user_idが整数型インデックスの場合
  -- Generated Columnを作成
  SELECT * FROM users WHERE user_id = '42';
  ALTER TABLE orders ADD COLUMN price_rounded INT AS (ROUND(price, 0)) STORED;
  -- 文字列 '42' が数値 42 に変換されるが、インデックスは使用される
  -- インデックスを作成
CREATE INDEX idx_price_rounded ON orders(price_rounded);
   
   
  -- しかし、以下はインデックスが使用されない
  -- インデックスが使用される
  SELECT * FROM users WHERE CAST(user_id AS CHAR) = '42';
  SELECT * FROM orders WHERE price_rounded = 100;
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
==== カンマ区切り数値の変換 ====
MySQL 8.0以降では、関数インデックスが直接サポートされている。<br>
<br>
  <syntaxhighlight lang="mysql">
  <syntaxhighlight lang="mysql">
  SELECT '1,234,567' + 0;
  -- MySQL 8.0以降
  -- 結果: 1 (カンマで数値部分が終了)
  CREATE INDEX idx_round_price ON orders((ROUND(price, 0)));
   
   
  -- 正しく変換するには、カンマを除去する
  -- インデックスが使用される
  SELECT CAST(REPLACE('1,234,567', ',', '') AS SIGNED);
  SELECT * FROM orders WHERE ROUND(price, 0) = 100;
-- 結果: 1234567
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
==== 浮動小数点数の比較 ====
==== NULLの扱い ====
<u>多くの数値関数は、NULL引数に対してNULLを返す。</u><br>
<br>
NULL処理の例を以下に示す。<br>
<br>
  <syntaxhighlight lang="mysql">
  <syntaxhighlight lang="mysql">
  SELECT 0.1 + 0.2 = 0.3;
  SELECT ABS(NULL);
  -- 結果: 0 (false) (浮動小数点誤差により不一致)
  -- 結果: NULL
SELECT ROUND(NULL, 2);
-- 結果: NULL
SELECT SQRT(NULL);
-- 結果: NULL
   
   
  SELECT ABS((0.1 + 0.2) - 0.3) < 0.0001;
  SELECT 10 + NULL;
  -- 結果: 1 (true) (誤差を考慮した比較)
  -- 結果: NULL (算術演算でもNULL)
   
   
-- または、DECIMAL型を使用
  SELECT 10 / NULL;
  SELECT CAST(0.1 AS DECIMAL(10,2)) + CAST(0.2 AS DECIMAL(10,2)) = CAST(0.3 AS DECIMAL(10,2));
  -- 結果: NULL
  -- 結果: 1 (true)
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
==== 日本語日付のCAST不可 ====
NULLを扱う場合は、<code>COALESCE</code> 関数 や <code>IFNULL</code> 関数を併用することを推奨する。<br>
<br>
  <syntaxhighlight lang="mysql">
  <syntaxhighlight lang="mysql">
  SELECT CAST('2024年8月15日' AS DATE);
  SELECT ROUND(COALESCE(price, 0), 2) FROM products;
  -- 結果: NULL (日本語日付は認識されない)
  -- NULLを0で置換してから丸め
SELECT IFNULL(quantity, 0) * price AS total FROM order_items;
-- NULLを0で置換
   
   
-- STR_TO_DATE関数を使用
  SELECT COALESCE(discount_rate, 0.0) FROM customers;
  SELECT STR_TO_DATE('2024年8月15日', '%Y年%m月%d日');
  -- NULL割引率を0.0で置換
  -- 結果: 2024-08-15
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
==== 大きな整数と浮動小数点の比較 ====
NULL伝播の例を以下に示す。<br>
<br>
  <syntaxhighlight lang="mysql">
  <syntaxhighlight lang="mysql">
  SELECT 9223372036854775807 = 9223372036854775808.0;
  SELECT price + tax;
  -- 結果: 1 (true) (浮動小数点の精度制限により誤った結果)
  -- priceまたはtaxがNULLなら結果はNULL
   
   
-- 整数同士で比較する
  SELECT COALESCE(price, 0) + COALESCE(tax, 0);
  SELECT 9223372036854775807 = CAST(9223372036854775808.0 AS SIGNED);
  -- NULLを0で置換してから加算
  -- 結果: 0 (false) (ただし、オーバーフローに注意)
  </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,Type Conversion,Cast,Convert,Implicit Conversion,Explicit Conversion,型変換,キャスト,データベース,電気回路,電子回路,基板,プリント基板
|keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,MySQL,Database,SQL,Numeric Functions,Math Functions,ROUND,ABS,SQRT,SIN,COS,POWER,LOG,数値関数,算術演算,三角関数,データベース,電気回路,電子回路,基板,プリント基板
|description={{PAGENAME}} - MySQLの型変換・キャストに関する包括的なリファレンス | This page is {{PAGENAME}} in our wiki about electronic circuits and SUSE Linux
|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)


戻り値を以下に示す。

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で置換してから加算