MochiuWiki : SUSE, EC, PCB
検索
個人用ツール
ログイン
Toggle dark mode
名前空間
ページ
議論
表示
閲覧
ソースを閲覧
履歴を表示
MySQL - 数値関数のソースを表示
提供: MochiuWiki : SUSE, EC, PCB
←
MySQL - 数値関数
あなたには「このページの編集」を行う権限がありません。理由は以下の通りです:
この操作は、次のグループのいずれかに属する利用者のみが実行できます:
管理者
、new-group。
このページのソースの閲覧やコピーができます。
== 概要 == MySQLでは、データ型間の変換が頻繁に発生する。<br> 型変換には、暗黙的な変換と明示的な変換の2種類が存在する。<br> <br> 暗黙的な型変換は、演算や比較の際にMySQLが自動的に実行する変換である。<br> 明示的な型変換は、<code>CAST</code> 関数や <code>CONVERT</code> 関数を使用してユーザが指定する変換である。<br> <br> 暗黙的な型変換は、便利である一方で、予期しない結果やパフォーマンスの低下を引き起こす場合がある。<br> 特に、WHERE句でカラムに対して型変換が適用されると、インデックスが使用されなくなる可能性が高い。<br> <br> MySQL 8.0.17以降では、<code>CAST</code> 関数 および <code>CONVERT</code> 関数で使用可能な型が拡張されている。<br> <code>FLOAT</code> 型、<code>DOUBLE</code> 型への変換がサポートされ、精度指定も可能になった。<br> <br> また、MySQL 8.0.22以降では、<code>YEAR</code> 型への変換、および <code>AT TIME ZONE</code> 演算子が追加された。<br> <br> 型変換の動作を正確に理解することは、データの整合性を保ち、パフォーマンスを最適化する上で重要である。<br> <br><br> == 暗黙的な型変換 == 暗黙的な型変換は、MySQLが自動的に実行する型変換である。<br> 演算子や関数が異なる型の引数を受け取った場合、MySQLは自動的に型を変換して処理を行う。<br> <br> ==== 暗黙的変換が発生する場面 ==== 暗黙的な型変換は、以下に示す場面で発生する。<br> <br> <center> {| class="wikitable" |+ 暗黙的な型変換が発生する場面 |- ! 場面 !! 説明 |- | 比較演算子を使用する場合 || <code>=</code>、<code>!=</code>、<code><</code>、<code>></code>、<code><=</code>、<code>>=</code> 等 |- | 算術演算子を使用する場合 || <code>+</code>、<code>-</code>、<code>*</code>、<code>/</code>、<code>%</code> 等 |- | 関数の引数として使用する場合 || <code>CONCAT</code> 関数、<code>SUBSTRING</code> 関数等 |- | INSERT文またはUPDATE文での値代入 || カラムの型と異なる型の値を挿入または更新する場合 |- | WHERE句での条件評価 || カラムと異なる型の値で比較する場合 |} </center> <br> 暗黙的変換の例を以下に示す。<br> <br> <u>暗黙的変換は、コードの記述を簡潔にする一方で、予期しない動作を引き起こす可能性がある。</u><br> <br> <syntaxhighlight lang="mysql"> SELECT '100' + 50; -- 結果: 150 (文字列 '100' が数値 100 に変換される) SELECT CONCAT(123, ' items'); -- 結果: '123 items' (数値 123 が文字列 '123' に変換される) SELECT * FROM users WHERE user_id = '42'; -- user_idが整数型の場合、文字列 '42' が数値 42 に変換される </syntaxhighlight> <br> ==== 文字列から数値への暗黙変換 ==== 文字列が数値として解釈される場合、MySQLは文字列の先頭から数値として読み取れる部分までを変換する。<br> <br> 変換ルールを以下に示す。<br> <br> <center> {| class="wikitable" |+ 文字列から数値への変換規則 |- ! 条件 !! 説明 |- | 先頭が数字の場合 || 数値として読み取れる部分まで変換 |- | 先頭が数字でない場合 || 0に変換 |- | 指数表記 (科学的表記法) をサポート || <code>1.5e2</code> は 150 に変換 |- | カンマ区切りは数値として認識されない || <code>1,234,567</code> は 1 に変換 (カンマで終了) |} </center> <br> 文字列から数値への変換例を以下に示す。<br> <br> <u>このルールにより、予期しない結果が生じる可能性がある。</u><br> <u>例えば、<code>'1,234,567'</code> という文字列は、1に変換される。</u><br> <br> <syntaxhighlight lang="mysql"> SELECT '123' + 0; -- 結果: 123 SELECT '123abc' + 0; -- 結果: 123 (先頭の数値部分のみ変換) SELECT 'abc123' + 0; -- 結果: 0 (先頭が数字でないため0に変換) SELECT '1.5e2' + 0; -- 結果: 150 (指数表記を解釈) SELECT '1,234,567' + 0; -- 結果: 1 (カンマで数値部分が終了) SELECT ' 456 ' + 0; -- 結果: 456 (前後の空白は無視) </syntaxhighlight> <br> ==== 数値から文字列への暗黙変換 ==== 数値が文字列として解釈される場面では、MySQLは数値を文字列に自動変換する。<br> <br> 数値から文字列への変換は、比較的直感的である。<br> <br> 文字列コンテキストの例を以下に示す。<br> <br> <syntaxhighlight lang="mysql"> SELECT CONCAT(2, ' items'); -- 結果: '2 items' (数値 2 が文字列 '2' に変換) SELECT CONCAT(123.45, ' dollars'); -- 結果: '123.45 dollars' SELECT CONCAT(NULL, ' test'); -- 結果: NULL </syntaxhighlight> <br> ==== 日付型の暗黙変換 ==== MySQLは、日付型の文字列表現を"緩やかな"フォーマットで受け入れる。<br> <br> 日付型の暗黙変換の特徴を以下に示す。<br> <br> <center> {| class="wikitable" |+ 文字列から日付/時刻への変換規則 |- ! 規則 !! 説明 |- | 区切り文字の柔軟性 || <code>-</code>、<code>/</code>、<code>#</code> 等の区切り文字を使用可能 |- | 区切り文字なしの形式 || <code>20240815</code> のような形式も認識 |- | 時刻部分のオプション || 日付のみ、または日付と時刻の両方を指定可能 |} </center> <br> 日付型の暗黙変換の例を以下に示す。<br> <br> <u>ただし、日本語の日付表記 (例: <code>2024年8月15日</code>) は認識されない。</u><br> <u>このような形式の日付を変換する場合は、<code>STR_TO_DATE</code> 関数を使用する。</u><br> <br> <syntaxhighlight lang="mysql"> SELECT CAST('2024-08-15' AS DATE); -- 結果: 2024-08-15 SELECT CAST('2024/08/15' AS DATE); -- 結果: 2024-08-15 (区切り文字 / を認識) SELECT CAST('2024#08#15' AS DATE); -- 結果: 2024-08-15 (区切り文字 # を認識) SELECT CAST('20240815' AS DATE); -- 結果: 2024-08-15 (区切り文字なしも認識) SELECT CAST('2024-08-15 14:30:00' AS DATETIME); -- 結果: 2024-08-15 14:30:00 </syntaxhighlight> <br><br> == 比較時の型変換ルール == MySQLは、異なる型の値を比較する際に、一定のルールに従って型変換を実行する。<br> <br> ==== 型変換の優先順位 ==== MySQLは、以下に示す優先順位で型変換を実行する。<br> <br> <center> {| class="wikitable" |+ 型変換の優先順位 |- ! 優先順位 !! 条件 !! 変換規則 |- | 1 || NULLの場合 || 結果は <code>NULL</code> (<code><=></code> 演算子は例外) |- | 2 || 両方が文字列の場合 || 文字列として比較 |- | 3 || 両方が整数の場合 || 整数として比較 |- | 4 || DECIMALが含まれる場合 || DECIMAL精度ルールに従って比較 |- | 5 || その他の場合 || 浮動小数点数として比較 |} </center> <br> 比較時の型変換の例を以下に示す。<br> <br> <syntaxhighlight lang="mysql"> SELECT 1 = '1'; -- 結果: 1 (true) (文字列 '1' が数値 1 に変換) SELECT 0 = 'abc'; -- 結果: 1 (true) (文字列 'abc' が数値 0 に変換) SELECT 1 = 1.0; -- 結果: 1 (true) (整数と浮動小数点の比較) SELECT 'abc' = 'ABC'; -- 結果: 1 (true) (デフォルトの照合順序は大文字小文字を区別しない) </syntaxhighlight> <br> ==== 文字列と数値の比較 ==== 文字列と数値を比較する場合、<u>文字列が数値に変換</u> される。<br> <br> 文字列と数値の比較例を以下に示す。<br> <br> この動作により、予期しない比較結果が生じる可能性がある。<br> 特に、<u>'abc' = 0 が true</u> となる点に注意すること。<br> <br> <syntaxhighlight lang="mysql"> SELECT 1 > '6x'; -- 結果: 0 (false) ('6x' は 6 に変換、1 > 6 は false) SELECT 7 > '6x'; -- 結果: 1 (true) ('6x' は 6 に変換、7 > 6 は true) SELECT 0 = 'x6'; -- 結果: 1 (true) ('x6' は 0 に変換、0 = 0 は true) SELECT 'abc' = 0; -- 結果: 1 (true) ('abc' は 0 に変換) SELECT '123' > 99; -- 結果: 1 (true) ('123' は 123 に変換、123 > 99 は true) </syntaxhighlight> <br> ==== 照合順序と比較 ==== 文字列同士の比較では、照合順序 (Collation) が比較結果に影響する。<br> <br> 大文字小文字を区別する比較を行う場合は、<code>BINARY</code> 演算子 または <code>COLLATE utf8mb4_bin</code> を使用する。<br> <br> 照合順序の影響を以下に示す。<br> <br> <syntaxhighlight lang="mysql"> SELECT 'abc' = 'ABC'; -- 結果: 1 (true) (デフォルトの照合順序は大文字小文字を区別しない) SELECT 'abc' = 'ABC' COLLATE utf8mb4_bin; -- 結果: 0 (false) (バイナリ比較では区別) SELECT BINARY 'abc' = 'ABC'; -- 結果: 0 (false) (BINARY演算子でバイナリ比較を強制) </syntaxhighlight> <br><br> == 明示的な型変換 == 明示的な型変換は、<code>CAST</code> 関数 または <code>CONVERT</code> 関数を使用して実行する。<br> これらの関数により、ユーザが意図した型変換を明確に指定できる。<br> <br> ==== CAST関数 ==== <code>CAST</code> 関数は、SQL標準の型変換関数である。<br> <br> 基本構文を以下に示す。<br> <br> <syntaxhighlight lang="mysql"> CAST(expr AS type [ARRAY]) </syntaxhighlight> <br> <center> {| class="wikitable" |+ <code>CAST</code>関数の引数 ! 引数 !! 説明 |- | <code>expr</code> || 変換する値または式 |- | <code>type</code> || 変換先の型 |- | <code>ARRAY</code> || JSON配列への変換 (オプション、MySQL 8.0.17以降) |} </center> <br> <code>CAST</code> 関数の使用例を以下に示す。<br> <br> <syntaxhighlight lang="mysql"> SELECT CAST('123' AS SIGNED); -- 結果: 123 (文字列を符号付き整数に変換) SELECT CAST(123.456 AS DECIMAL(5,2)); -- 結果: 123.46 (浮動小数点数を固定小数点数に変換、四捨五入) SELECT CAST('2024-08-15' AS DATE); -- 結果: 2024-08-15 (文字列を日付型に変換) SELECT CAST('2024-08-15 14:30:00' AS DATETIME); -- 結果: 2024-08-15 14:30:00 (文字列を日時型に変換) SELECT CAST(123 AS CHAR); -- 結果: '123' (数値を文字列に変換) </syntaxhighlight> <br> ==== CONVERT関数 ==== <code>CONVERT</code> 関数は、MySQL独自の型変換関数である。<br> <code>CONVERT</code> 関数には、2つの構文が存在する。<br> <br> 基本構文を以下に示す。<br> <br> <syntaxhighlight lang="mysql"> CONVERT(expr, type) CONVERT(expr USING transcoding_name) </syntaxhighlight> <br> <center> {| class="wikitable" |+ <code>CONVERT</code>関数の構文 ! 構文 !! 説明 |- | <code>CONVERT(expr, type)</code> || <code>CAST</code>関数と同様の型変換 |- | <code>CONVERT(expr USING transcoding_name)</code> || 文字セット変換 |} </center> <br> <code>CONVERT</code> 関数の使用例を以下に示す。<br> <br> <syntaxhighlight lang="mysql"> SELECT CONVERT('123', SIGNED); -- 結果: 123 SELECT CONVERT(123.456, DECIMAL(5,2)); -- 結果: 123.46 SELECT CONVERT('Hello' USING utf8mb4); -- 結果: 'Hello' (文字セットをutf8mb4に変換) SELECT CONVERT('データ' USING latin1); -- エラーまたは文字化け (latin1は日本語をサポートしない) </syntaxhighlight> <br> 文字セット指定付き <code>CAST</code> 関数の構文を以下に示す。<br> <br> <syntaxhighlight lang="mysql"> CAST(expr AS CHAR CHARACTER SET charset_name) </syntaxhighlight> <br> 文字セット指定の例を以下に示す。<br> <br> <syntaxhighlight lang="mysql"> SELECT CAST('Hello' AS CHAR CHARACTER SET utf8mb4); -- 結果: 'Hello' SELECT CAST('データベース' AS CHAR CHARACTER SET utf8mb4); -- 結果: 'データベース' </syntaxhighlight> <br> ==== CAST / CONVERTで使用可能な型の詳細 ==== <code>CAST</code> 関数 および <code>CONVERT</code> 関数では、以下に示す型への変換がサポートされている。<br> <br> <center> {| class="wikitable" |+ サポートされる型の一覧 ! 型 !! 説明 !! 追加されたバージョン |- | <code>BINARY[(N)]</code> || バイナリ文字列型 || |- | <code>CHAR[(N)]</code> || 固定長文字列型 || |- | <code>DATE</code> || 日付型 || |- | <code>DATETIME</code> || 日時型 || |- | <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> <br> ===== BINARY / CHAR ===== <code>BINARY</code> 型 および <code>CHAR</code> 型への変換は、文字列またはバイナリ文字列を生成する。<br> <br> <code>BINARY[(N)]</code> の場合、<code>N</code> はバイト数を指定する。<br> <code>CHAR[(N)]</code> の場合、<code>N</code> は文字数ではなくバイト数を指定する点に注意すること。<br> <br> <syntaxhighlight lang="mysql"> SELECT CAST(123 AS CHAR); -- 結果: '123' SELECT CAST('Hello' AS BINARY(10)); -- 結果: 'Hello\0\0\0\0\0' (10バイトに拡張、NULLバイトでパディング) SELECT CAST('Hello World' AS CHAR(5)); -- 結果: 'Hello' (5バイトに切り詰め) </syntaxhighlight> <br> ===== 数値型 ===== 数値型への変換には、整数型、固定小数点型、浮動小数点型が含まれる。<br> <br> <center> {| class="wikitable" |+ 数値型への変換 ! 型 !! 説明 |- | <code>SIGNED [INTEGER]</code> || 符号付き整数型 (-9223372036854775808 ~ 9223372036854775807) |- | <code>UNSIGNED [INTEGER]</code> || 符号なし整数型 (0 ~ 18446744073709551615) |- | <code>DECIMAL[(M[,D])]</code> || 固定小数点型 (M: 精度、D: 小数点以下桁数) |- | <code>FLOAT[(p)]</code> || 単精度浮動小数点型 (p: 精度 0-53) |- | <code>DOUBLE</code> || 倍精度浮動小数点型 |- | <code>REAL</code> || REAL型 (REAL_AS_FLOATモード設定時はFLOAT、それ以外はDOUBLE) |} </center> <br> <code>FLOAT[(p)]</code> の精度指定について以下に示す。<br> <br> <center> {| class="wikitable" |+ <code>FLOAT[(p)]</code> の精度指定 |- ! 精度 <code>p</code> の範囲 !! 変換先 |- | 0〜24 || <code>FLOAT</code> 型 (単精度浮動小数点) |- | 25〜53 || <code>DOUBLE</code> 型 (倍精度浮動小数点) |} </center> <br> 数値型への変換の例を以下に示す。<br> <br> <syntaxhighlight lang="mysql"> SELECT CAST('123' AS SIGNED); -- 結果: 123 SELECT CAST('-456' AS SIGNED); -- 結果: -456 SELECT CAST('789' AS UNSIGNED); -- 結果: 789 SELECT CAST('-123' AS UNSIGNED); -- 結果: 18446744073709551493 (オーバーフロー) SELECT CAST(123.456 AS DECIMAL(5,2)); -- 結果: 123.46 (四捨五入) SELECT CAST('123.456' AS FLOAT); -- 結果: 123.456 SELECT CAST('123.456' AS DOUBLE); -- 結果: 123.456 SELECT CAST('1.23e2' AS DOUBLE); -- 結果: 123 (指数表記を解釈) </syntaxhighlight> <br> ===== 日付・時刻型 ===== 日付型および時刻型への変換には、以下に示す型が含まれる。<br> <br> <center> {| class="wikitable" |+ 日付・時刻型への変換 ! 型 !! 形式 !! 説明 |- | <code>DATE</code> || YYYY-MM-DD || 日付型 |- | <code>TIME</code> || HH:MM:SS || 時刻型 |- | <code>DATETIME</code> || YYYY-MM-DD HH:MM:SS || 日時型 |- | <code>YEAR</code> || YYYY || 年型 (MySQL 8.0.22以降) |} </center> <br> 日付・時刻型への変換の例を以下に示す。<br> <br> <syntaxhighlight lang="mysql"> SELECT CAST('2024-08-15' AS DATE); -- 結果: 2024-08-15 SELECT CAST('14:30:00' AS TIME); -- 結果: 14:30:00 SELECT CAST('2024-08-15 14:30:00' AS DATETIME); -- 結果: 2024-08-15 14:30:00 SELECT CAST('2024' AS YEAR); -- 結果: 2024 (MySQL 8.0.22以降) SELECT CAST('2024-08-15 14:30:00' AS DATE); -- 結果: 2024-08-15 (時刻部分は切り捨て) SELECT CAST('2024-08-15 14:30:00' AS TIME); -- 結果: 14:30:00 (日付部分は切り捨て) </syntaxhighlight> <br> <code>AT TIME ZONE</code> 演算子による時刻変換 (MySQL 8.0.22以降) を以下に示す。<br> <br> <syntaxhighlight lang="mysql"> SELECT CAST('2024-08-15 14:30:00' AS DATETIME) AT TIME ZONE '+00:00'; -- 結果: UTCタイムゾーンに変換 </syntaxhighlight> <br> ===== JSON ===== <code>JSON</code> 型への変換は、文字列、数値、オブジェクト、配列をJSON形式に変換する。<br> <br> <syntaxhighlight lang="mysql"> SELECT CAST('{}' AS JSON); -- 結果: {} (空のJSONオブジェクト) SELECT CAST('[1,2,3]' AS JSON); -- 結果: [1,2,3] (JSON配列) SELECT CAST(123 AS JSON); -- 結果: 123 (JSON数値) SELECT CAST('"Hello"' AS JSON); -- 結果: "Hello" (JSON文字列) SELECT CAST('{"name":"Alice","age":30}' AS JSON); -- 結果: {"name":"Alice","age":30} (JSONオブジェクト) </syntaxhighlight> <br><br> == JSON関連の型変換 == MySQL 8.0では、JSON型と他の型の間での変換が強化されている。<br> <br> ==== JSON型への変換 ==== JSON型への変換は、<code>CAST</code> 関数を使用して実行する。<br> <br> <syntaxhighlight lang="mysql"> SELECT CAST('{"name":"Alice"}' AS JSON); -- 結果: {"name":"Alice"} SELECT CAST('[1,2,3,4,5]' AS JSON); -- 結果: [1,2,3,4,5] SELECT CAST(123 AS JSON); -- 結果: 123 SELECT CAST(true AS JSON); -- 結果: true SELECT CAST(NULL AS JSON); -- 結果: null (JSONのnull値) </syntaxhighlight> <br> ==== JSON型からの変換 ==== JSON型から他の型への変換には、<code>JSON_UNQUOTE</code> 関数 と <code>JSON_EXTRACT</code> 関数を組み合わせる方法がある。<br> <br> <syntaxhighlight lang="mysql"> SET @json = '{"name":"Alice","age":30}'; SELECT JSON_EXTRACT(@json, '$.name'); -- 結果: "Alice" (JSON文字列、ダブルクォート付き) SELECT JSON_UNQUOTE(JSON_EXTRACT(@json, '$.name')); -- 結果: Alice (ダブルクォートを除去) SELECT CAST(JSON_EXTRACT(@json, '$.age') AS SIGNED); -- 結果: 30 (数値に変換) </syntaxhighlight> <br> MySQL 8.0.21以降では、<code>JSON_VALUE</code> 関数が利用可能である。<br> <br> <code>JSON_VALUE</code> 関数の構文を以下に示す。<br> <br> <syntaxhighlight lang="mysql"> JSON_VALUE(json_doc, path [RETURNING type] [on_empty] [on_error]) </syntaxhighlight> <br> <center> {| class="wikitable" |+ <code>JSON_VALUE</code>関数の引数 ! 引数 !! 説明 |- | <code>json_doc</code> || JSON文書 |- | <code>path</code> || JSONパス式 |- | <code>RETURNING type</code> || 戻り型 (オプション、デフォルト: VARCHAR(512)) |- | <code>on_empty</code> || 値が存在しない場合の動作 |- | <code>on_error</code> || エラー発生時の動作 |} </center> <br> <code>JSON_VALUE</code> 関数で使用可能な型を以下に示す。<br> <br> <center> {| class="wikitable" |+ JSON_VALUE関数で使用可能な型 |- ! 分類 !! 型 |- | 数値型 || <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> |- | 文字列型 || <code>CHAR</code> |- | その他 || <code>JSON</code> |} </center> <br> <code>JSON_VALUE</code> 関数の使用例を以下に示す。<br> <br> <syntaxhighlight lang="mysql"> SET @json = '{"name":"Alice","age":30,"salary":50000.50}'; SELECT JSON_VALUE(@json, '$.name'); -- 結果: 'Alice' (デフォルトはVARCHAR(512)) SELECT JSON_VALUE(@json, '$.age' RETURNING SIGNED); -- 結果: 30 (符号付き整数に変換) SELECT JSON_VALUE(@json, '$.salary' RETURNING DECIMAL(10,2)); -- 結果: 50000.50 (固定小数点数に変換) SELECT JSON_VALUE(@json, '$.unknown' RETURNING SIGNED NULL ON EMPTY); -- 結果: NULL (値が存在しない場合はNULLを返す) SELECT JSON_VALUE(@json, '$.unknown' RETURNING SIGNED DEFAULT 0 ON EMPTY); -- 結果: 0 (値が存在しない場合は0を返す) SELECT JSON_VALUE(@json, '$.invalid' RETURNING SIGNED ERROR ON ERROR); -- エラー発生 (変換エラー時にエラーを返す) </syntaxhighlight> <br> <code>ON EMPTY</code> 句および <code>ON ERROR</code> 句の動作を以下に示す。<br> <br> <center> {| class="wikitable" |+ ON EMPTY / ON ERROR句の動作 ! 句 !! 説明 |- | <code>NULL ON EMPTY</code> || 値が存在しない場合、NULLを返す (デフォルト) |- | <code>DEFAULT value ON EMPTY</code> || 値が存在しない場合、指定したデフォルト値を返す |- | <code>ERROR ON EMPTY</code> || 値が存在しない場合、エラーを発生 |- | <code>NULL ON ERROR</code> || 変換エラー時、NULLを返す (デフォルト) |- | <code>DEFAULT value ON ERROR</code> || 変換エラー時、指定したデフォルト値を返す |- | <code>ERROR ON ERROR</code> || 変換エラー時、エラーを発生 |} </center> <br> <u>※注意</u><br> <u><code>ON EMPTY</code> 句は、<code>ON ERROR</code> 句より前に置く必要がある。</u><br> <br> ==== JSONと他の型の比較 ==== JSON型と他の型を比較する場合、MySQLは自動的に型変換を実行する。<br> <br> <syntaxhighlight lang="mysql"> SET @json = '{"value":123}'; SELECT JSON_EXTRACT(@json, '$.value') = 123; -- 結果: 1 (true) (JSON数値と整数を比較) SELECT JSON_EXTRACT(@json, '$.value') = '123'; -- 結果: 1 (true) (JSON数値と文字列を比較) </syntaxhighlight> <br><br> == 型変換に関する注意点 == ==== データ損失のリスク ==== 型変換により、データが損失または変更される場合がある。<br> <br> データ損失が発生する例を以下に示す。<br> <br> * 固定小数点数から整数への変換 *: 小数部が切り捨てられる *: <syntaxhighlight lang="mysql"> SELECT CAST(123.456 AS SIGNED); -- 結果: 123 (小数部 .456 が切り捨て) </syntaxhighlight> *: <br> * 浮動小数点数から固定小数点数への変換 *: 丸め誤差が発生する可能性 *: <syntaxhighlight lang="mysql"> SELECT CAST(123.456789 AS DECIMAL(5,2)); -- 結果: 123.46 (四捨五入) </syntaxhighlight> *: <br> * 文字列から整数への変換 *: 数値以外の文字が喪失 *: <syntaxhighlight lang="mysql"> SELECT CAST('123abc' AS SIGNED); -- 結果: 123 ('abc' が喪失) SELECT CAST('abc123' AS SIGNED); -- 結果: 0 (全ての文字が喪失) </syntaxhighlight> *: <br> * 日時型から日付型への変換 *: 時刻部分が切り捨てられる *: <syntaxhighlight lang="mysql"> SELECT CAST('2024-08-15 14:30:00' AS DATE); -- 結果: 2024-08-15 (時刻部分 14:30:00 が切り捨て) </syntaxhighlight> <br> ==== インデックスへの影響 ==== WHERE句でカラムに対して型変換を適用すると、インデックスが使用されなくなる。<br> これにより、クエリのパフォーマンスが大幅に低下する可能性がある。<br> <br> * 良い例 *: <syntaxhighlight lang="mysql"> -- 値側で型変換を行う SELECT * FROM users WHERE user_id = 123; -- インデックスが使用される -- または、CASTを使わずに比較 SELECT * FROM users WHERE user_id = CAST('123' AS SIGNED); -- インデックスが使用される </syntaxhighlight> *: <br> * 悪い例 *: <syntaxhighlight lang="mysql"> -- user_idが整数型の場合 SELECT * FROM users WHERE CAST(user_id AS CHAR) = '123'; -- インデックスが使用されない </syntaxhighlight> <br> <u>カラムに対して関数または型変換を適用しないことが、インデックスを有効活用するための基本原則である。</u><br> <br> ==== NULLの扱い ==== <code>CAST</code> 関数 および <code>CONVERT</code> 関数は、<code>NULL</code> を変換すると <code>NULL</code> を返す。<br> <br> <syntaxhighlight lang="mysql"> SELECT CAST(NULL AS SIGNED); -- 結果: NULL SELECT CAST(NULL AS CHAR); -- 結果: NULL SELECT CAST(NULL AS DATE); -- 結果: NULL </syntaxhighlight> <br> <code>NULL</code> を別の値に置き換える場合は、<code>COALESCE</code> 関数 または <code>IFNULL</code> 関数を使用する。<br> <br> <syntaxhighlight lang="mysql"> SELECT COALESCE(CAST(NULL AS SIGNED), 0); -- 結果: 0 SELECT IFNULL(CAST(NULL AS SIGNED), -1); -- 結果: -1 </syntaxhighlight> <br> ==== 文字列と数値の比較でインデックスが使用されない ==== <syntaxhighlight lang="mysql"> -- user_idが整数型インデックスの場合 SELECT * FROM users WHERE user_id = '42'; -- 文字列 '42' が数値 42 に変換されるが、インデックスは使用される -- しかし、以下はインデックスが使用されない SELECT * FROM users WHERE CAST(user_id AS CHAR) = '42'; </syntaxhighlight> <br> ==== カンマ区切り数値の変換 ==== <syntaxhighlight lang="mysql"> SELECT '1,234,567' + 0; -- 結果: 1 (カンマで数値部分が終了) -- 正しく変換するには、カンマを除去する SELECT CAST(REPLACE('1,234,567', ',', '') AS SIGNED); -- 結果: 1234567 </syntaxhighlight> <br> ==== 浮動小数点数の比較 ==== <syntaxhighlight lang="mysql"> SELECT 0.1 + 0.2 = 0.3; -- 結果: 0 (false) (浮動小数点誤差により不一致) SELECT ABS((0.1 + 0.2) - 0.3) < 0.0001; -- 結果: 1 (true) (誤差を考慮した比較) -- または、DECIMAL型を使用 SELECT CAST(0.1 AS DECIMAL(10,2)) + CAST(0.2 AS DECIMAL(10,2)) = CAST(0.3 AS DECIMAL(10,2)); -- 結果: 1 (true) </syntaxhighlight> <br> ==== 日本語日付のCAST不可 ==== <syntaxhighlight lang="mysql"> SELECT CAST('2024年8月15日' AS DATE); -- 結果: NULL (日本語日付は認識されない) -- STR_TO_DATE関数を使用 SELECT STR_TO_DATE('2024年8月15日', '%Y年%m月%d日'); -- 結果: 2024-08-15 </syntaxhighlight> <br> ==== 大きな整数と浮動小数点の比較 ==== <syntaxhighlight lang="mysql"> SELECT 9223372036854775807 = 9223372036854775808.0; -- 結果: 1 (true) (浮動小数点の精度制限により誤った結果) -- 整数同士で比較する SELECT 9223372036854775807 = CAST(9223372036854775808.0 AS SIGNED); -- 結果: 0 (false) (ただし、オーバーフローに注意) </syntaxhighlight> <br><br> {{#seo: |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,型変換,キャスト,データベース,電気回路,電子回路,基板,プリント基板 |description={{PAGENAME}} - MySQLの型変換・キャストに関する包括的なリファレンス | This page is {{PAGENAME}} in our wiki about electronic circuits and SUSE Linux |image=/resources/assets/MochiuLogo_Single_Blue.png }} __FORCETOC__ [[カテゴリ:MySQL]]
MySQL - 数値関数
に戻る。
案内
メインページ
最近の更新
おまかせ表示
MediaWiki についてのヘルプ
ツール
リンク元
関連ページの更新状況
特別ページ
ページ情報
We ask for
Donations
Collapse