※この記事にはアフィリエイト広告(プロモーション)が含まれます。
この記事の出力は MySQL 8.4.11(Ubuntu 26.04、sql_mode は既定)で採りました。
まず見る(結論)
SELECT CAST('123' AS SIGNED); -- 123(整数)
SELECT CAST('123' AS UNSIGNED); -- 123(符号なし整数)
SELECT CONVERT('123', SIGNED); -- 123(CAST と同じ)
SELECT CAST('12.345' AS DECIMAL(10,2)); -- 12.35
SELECT CAST(123 AS CHAR); -- '123'
SELECT LPAD(5, 5, '0'); -- '00005'
CAST('123' AS INT)とAS INTEGERはERROR 1064。整数はSIGNEDかUNSIGNED(SIGNED INTEGERは通る)- 変換できない文字列はエラーにならず 0 や途中までの数になる。出るのは警告 1292 だけ
CAST で指定できる型
| 指定 | CAST('123' AS …) |
|---|---|
SIGNED / SIGNED INTEGER / UNSIGNED |
123 |
DECIMAL / DECIMAL(10,2) |
123 / 123.00 |
FLOAT / DOUBLE |
123 |
CHAR |
‘123’ |
CAST の型は列の型と同じ名前ではありません。DECIMAL を桁なしで書くと DECIMAL(10,0) になり、CAST('12.5' AS DECIMAL) は 13 でした。
変換できない文字列の結果
| 式 | 結果 |
|---|---|
CAST(' 123 ' AS SIGNED) |
123 |
CAST('1,234' AS SIGNED) |
1 |
CAST('123abc' AS SIGNED) |
123 |
CAST('abc' AS SIGNED) / CAST('' AS SIGNED) |
0 |
CAST('123' AS SIGNED)(全角) |
0 |
CAST('1e3' AS SIGNED) |
1('1e3' + 0 と AS DECIMAL は 1000) |
CAST('99999999999999999999' AS SIGNED) |
-1 |
CAST(-1 AS UNSIGNED) |
18446744073709551615 |
先頭から数として読める所までを使い、残りを捨てます。SHOW WARNINGS に Warning 1292 Truncated incorrect INTEGER value: '1,234' が出るだけです(CAST(-1 AS UNSIGNED) は警告も出ません)。PostgreSQL はこれらを全部エラーにします(PostgreSQLの型変換)。
文字列の小数と数値の小数で丸めが違う
| 式 | 結果 |
|---|---|
CAST('12.5' AS SIGNED) |
12 |
CAST(12.5 AS SIGNED) / CAST(-12.5 AS SIGNED) |
13 / -13 |
CAST(CAST('12.5' AS DECIMAL(10,1)) AS SIGNED) |
13 |
ROUND('12.5') / ROUND(12.5) |
12 / 13 |
ROUND に文字列を渡すと DOUBLE として計算されます。四捨五入したいなら先に DECIMAL にします。
カンマ入り・全角の文字列
SELECT CAST(REPLACE('1,234', ',', '') AS SIGNED); -- 1234
SELECT CAST(FORMAT(1234567.891, 2) AS DECIMAL(12,2)); -- 1.00(FORMAT の結果は戻せない)
全角数字は MySQL の関数だけでは変換できないので、取り込む前に半角にそろえます。
暗黙の変換(+ 0 と比較)
文字列に + 0 すると数値になります。'123abc' + 0 は 123、'abc' + 0 は 0 で、警告は Truncated incorrect DOUBLE value です。'10' + '20' は 30 です。文字列をつなぐのは CONCAT で、10 || 20 は 1(論理和)でした。
文字列の列を数値で検索すると
索引のある code(varchar)に '10' '10abc' ' 10' '08' などを入れて比べました。
| SQL | 返った行 | EXPLAIN |
|---|---|---|
WHERE code = 10 |
'10' '10abc' ' 10' |
type: ALL(key は NULL) |
WHERE code = '10' |
'10' |
type: ref(key: code) |
WHERE code = 8 |
'08' |
— |
文字列の列と数値を比べると、列の値を1行ずつ数値に変換してから比較します。文字列の列には文字列('10')で条件を書きます。EXPLAIN の見方は EXPLAIN の記事に書きました。
数字の文字列を数値順に並べる
| ORDER BY | 並び |
|---|---|
code |
‘ 10’, 08, 10, 100, 10abc, 2, 9 |
code + 0, code |
2, 08, 9, ‘ 10’, 10, 10abc, 100 |
CAST(code AS UNSIGNED), code |
上と同じ |
LENGTH(code), code |
2, 9, 08, 10, ‘ 10’, 100, 10abc |
LENGTH で並べる方法は、'08' のような 0 始まりや空白が混ざると崩れます。
SUM・INSERT・列の型変更
SUM(amount_txt)は'1,200'を 1、'abc'を 0 として足し、警告を出すだけで863を返した。正しい合計(2062)はSUM(REPLACE(amount_txt, ',', ''))をWHERE REPLACE(amount_txt, ',', '') REGEXP '^[0-9]+$'で数字だけの行に絞って求めた- int 列への
INSERTは既定のsql_mode(STRICT_TRANS_TABLESあり)で'12abc'がERROR 1265 Data truncated、''がERROR 1366 Incorrect integer value。'12.5'は13、' 12 'は12で入った sql_mode = ''にすると'12abc'は12、''は0で、警告付きで入るALTER TABLE codes MODIFY code intは数字以外の行があるとERROR 1265 Data truncated for column 'code' at row 6。先にUPDATE ... WHERE code NOT REGEXP '^[0-9]+$'で直すと通り、'08'は 8 になった(ALTER TABLE の記事)
数値 → 文字列・0埋め
SELECT CONCAT(123, ''); -- '123'
SELECT LPAD(123456, 5, '0'); -- '12345'(長いと右が切れる)
SELECT FORMAT(1234567.891, 2); -- '1,234,567.89'
LPAD を使うときは、値が指定した長さに収まるかを先に確かめます。
割り算と日付
7 / 2は3.5000(小数4桁はdiv_precision_incrementの既定値)。整数の商は7 DIV 2で3。CAST(7 / 2 AS SIGNED)は4(四捨五入)CAST('2026/11/08' AS DATE)は通るが、8.4 では区切りの/に警告 4095(非推奨)が出る。CAST('2026-02-30' AS DATE)は警告付きで NULL。書式が決まっている文字列はSTR_TO_DATEを使う(DATE_FORMAT の記事)
関連: MySQLの文字列結合 / ERROR 1366「Incorrect string value」 / MySQLの日付計算