「文字列を数値として計算したいのにエラーが出る…」 「日付のフォーマットを変更したいけど、やり方が分からない」 「型が合わなくてJOINできない!」
こんな悩みを抱えていませんか?
PostgreSQLでデータを扱っていると、型変換(キャスト)は避けて通れない重要なスキルです。 適切な型変換ができれば、データの加工も、複雑な集計も、すべてがスムーズになります。
この記事では、PostgreSQLの型変換について、基本的な使い方から実践的なテクニックまで、実例たっぷりで解説します。 もう「型が違います」エラーに悩まされることはありません!
型変換の基本:なぜ必要なの?

データ型って何?
データ型とは、データの「種類」を定義するものです。 数値は数値として、文字は文字として、日付は日付として扱う必要があるんです。
主要なデータ型:
- 数値型:INTEGER, BIGINT, NUMERIC, REAL
- 文字型:VARCHAR, TEXT, CHAR
- 日付型:DATE, TIMESTAMP, TIME
- 論理型:BOOLEAN
- その他:JSON, UUID, ARRAY
型変換が必要になる場面
よくあるケース:
- 文字列として保存された数値を計算したい
-- '100' + '200' を 300 として計算
- 日付を特定のフォーマットで表示したい
-- 2025-09-14 を 2025年9月14日 として表示
- 異なる型の列を結合(JOIN)したい
-- user_id (INTEGER) と user_code (VARCHAR) を結合
- CSVインポート後のデータ整形
-- すべて文字列として入ったデータを適切な型に
3つの型変換方法:使い分けをマスター
方法1:CAST関数(標準SQL準拠)
最も標準的な型変換方法です。他のデータベースでも使えるので、覚えておくと便利!
基本構文:
CAST(値 AS 変換後の型)
実例:文字列を数値に変換
-- 文字列 '123' を整数に変換
SELECT CAST('123' AS INTEGER);
-- 結果: 123
-- 小数を含む文字列を数値に変換
SELECT CAST('123.45' AS NUMERIC);
-- 結果: 123.45
-- 複数の変換を組み合わせる
SELECT
CAST('100' AS INTEGER) + CAST('200' AS INTEGER) AS 合計;
-- 結果: 300
実例:日付の変換
-- 文字列を日付型に変換
SELECT CAST('2025-09-14' AS DATE);
-- 結果: 2025-09-14
-- タイムスタンプに変換
SELECT CAST('2025-09-14 15:30:00' AS TIMESTAMP);
-- 結果: 2025-09-14 15:30:00
方法2:::演算子(PostgreSQL独自の便利機能)
PostgreSQL特有の記法ですが、短くて書きやすいのが特徴です。
基本構文:
値::変換後の型
実例:スッキリ書ける型変換
-- CAST関数と同じ結果を、より短く書ける
SELECT '123'::INTEGER;
-- 結果: 123
-- 連続した変換もスッキリ
SELECT '123.45'::NUMERIC::INTEGER;
-- 結果: 123 (小数点以下切り捨て)
-- テーブルのカラムに対して使用
SELECT
user_id::TEXT,
created_at::DATE
FROM users;
CASTと::の使い分け:
- CAST:標準SQL準拠、可読性重視、他DBとの互換性
- :::PostgreSQL専用、簡潔性重視、頻繁な変換時
方法3:型変換関数(特定用途に特化)
特定の変換に特化した関数群です。より細かい制御が可能!
主要な型変換関数:
-- 文字列変換
SELECT TO_CHAR(123.45, '999.99');
-- 結果: ' 123.45'
SELECT TO_CHAR(CURRENT_DATE, 'YYYY年MM月DD日');
-- 結果: '2025年09月14日'
-- 数値変換
SELECT TO_NUMBER('123,456', '999,999');
-- 結果: 123456
-- 日付変換
SELECT TO_DATE('2025/09/14', 'YYYY/MM/DD');
-- 結果: 2025-09-14
SELECT TO_TIMESTAMP('2025-09-14 15:30:00', 'YYYY-MM-DD HH24:MI:SS');
-- 結果: 2025-09-14 15:30:00
暗黙的型変換と明示的型変換
暗黙的型変換(自動変換)
PostgreSQLが自動的に型を変換してくれる場合があります。
自動変換される例:
-- 整数と小数の計算(整数が自動的に小数に変換)
SELECT 10 + 3.14;
-- 結果: 13.14
-- 文字列と数値の比較(コンテキストによる)
SELECT * FROM products WHERE price > '100';
-- '100' が自動的に数値として解釈される
注意点: 暗黙的型変換に頼りすぎると、予期しない結果になることがあります!
-- 意図しない結果の例
SELECT '10' + '20';
-- エラー: 演算子が存在しません
-- 明示的に変換すれば OK
SELECT '10'::INTEGER + '20'::INTEGER;
-- 結果: 30
明示的型変換(推奨)
常に明示的に型変換することを推奨します!
理由:
- コードの意図が明確になる
- エラーの原因を特定しやすい
- パフォーマンスが向上する場合がある
-- 良い例:明示的な型変換
SELECT
user_id::TEXT || '_' || created_at::TEXT AS user_key
FROM users;
-- 悪い例:暗黙的な変換に依存
SELECT
user_id || '_' || created_at AS user_key -- エラーの可能性
FROM users;
よく使う型変換パターン集

文字列 ⇔ 数値
文字列 → 数値:
-- 基本的な変換
SELECT '123'::INTEGER;
SELECT '123.45'::NUMERIC;
SELECT '1.23e5'::REAL; -- 科学記数法
-- NULL や空文字の処理
SELECT
CASE
WHEN NULLIF(price_text, '') IS NULL THEN 0
ELSE price_text::NUMERIC
END AS price
FROM products;
-- カンマ区切りの数値
SELECT REPLACE('1,234,567', ',', '')::INTEGER;
-- 結果: 1234567
数値 → 文字列:
-- シンプルな変換
SELECT 123::TEXT;
-- フォーマット付き変換
SELECT TO_CHAR(1234567.89, 'FM999,999,999.00');
-- 結果: '1,234,567.89'
SELECT TO_CHAR(0.75, 'FM990.0%');
-- 結果: '75.0%'
日付 ⇔ 文字列
文字列 → 日付:
-- 標準フォーマット
SELECT '2025-09-14'::DATE;
-- カスタムフォーマット
SELECT TO_DATE('14/09/2025', 'DD/MM/YYYY');
SELECT TO_DATE('2025年9月14日', 'YYYY"年"MM"月"DD"日"');
-- タイムスタンプへの変換
SELECT '2025-09-14 15:30:00'::TIMESTAMP;
SELECT TO_TIMESTAMP('14-Sep-2025 3:30 PM', 'DD-Mon-YYYY HH:MI AM');
日付 → 文字列:
-- 様々なフォーマット
SELECT TO_CHAR(CURRENT_DATE, 'YYYY/MM/DD');
-- 結果: '2025/09/14'
SELECT TO_CHAR(CURRENT_DATE, 'Day, DD Month YYYY');
-- 結果: 'Saturday, 14 September 2025'
SELECT TO_CHAR(CURRENT_TIMESTAMP, 'YYYY-MM-DD HH24:MI:SS');
-- 結果: '2025-09-14 15:30:45'
-- 日本語フォーマット
SELECT TO_CHAR(CURRENT_DATE, 'YYYY"年"MM"月"DD"日"');
-- 結果: '2025年09月14日'
BOOLEAN ⇔ その他
文字列/数値 → BOOLEAN:
-- 文字列から
SELECT 'true'::BOOLEAN; -- TRUE
SELECT 't'::BOOLEAN; -- TRUE
SELECT 'yes'::BOOLEAN; -- TRUE
SELECT '1'::BOOLEAN; -- TRUE
SELECT 'false'::BOOLEAN; -- FALSE
SELECT 'f'::BOOLEAN; -- FALSE
SELECT 'no'::BOOLEAN; -- FALSE
SELECT '0'::BOOLEAN; -- FALSE
-- 数値から(0以外はTRUE)
SELECT (1)::BOOLEAN; -- TRUE
SELECT (0)::BOOLEAN; -- FALSE
BOOLEAN → 文字列/数値:
-- 文字列へ
SELECT TRUE::TEXT; -- 'true'
SELECT FALSE::TEXT; -- 'false'
-- 数値へ
SELECT TRUE::INTEGER; -- 1
SELECT FALSE::INTEGER; -- 0
-- CASE文を使った変換
SELECT
CASE WHEN is_active
THEN 'アクティブ'
ELSE '非アクティブ'
END AS status
FROM users;
JSON型との変換
通常の型 → JSON
-- 文字列をJSONに
SELECT '"Hello World"'::JSON;
-- 数値をJSONに
SELECT '123'::JSON;
-- 配列をJSONに
SELECT '[1, 2, 3]'::JSON;
-- オブジェクトをJSONに
SELECT '{"name": "田中", "age": 30}'::JSON;
-- テーブルデータをJSONに変換
SELECT row_to_json(users) FROM users;
-- 特定のカラムだけJSONに
SELECT json_build_object(
'id', user_id,
'name', user_name,
'created', created_at::TEXT
) AS user_json
FROM users;
JSON → 通常の型
-- JSONから値を取り出して型変換
SELECT
(data->>'age')::INTEGER AS age,
(data->>'price')::NUMERIC AS price,
(data->>'is_active')::BOOLEAN AS is_active,
(data->>'created_at')::TIMESTAMP AS created_at
FROM json_table;
-- JSON配列を展開
SELECT
value::INTEGER AS number
FROM json_array_elements('[1, 2, 3, 4, 5]'::JSON);
エラー対処法とベストプラクティス
よくあるエラーと解決法
エラー1:「invalid input syntax」
-- エラーになる例
SELECT 'abc'::INTEGER;
-- ERROR: invalid input syntax for type integer: "abc"
-- 解決法:事前チェック
SELECT
CASE
WHEN value ~ '^\d+$' THEN value::INTEGER
ELSE NULL
END AS safe_number
FROM data_table;
エラー2:「cannot cast type」
-- エラーになる例
SELECT ARRAY[1,2,3]::TEXT;
-- ERROR: cannot cast type integer[] to text
-- 解決法:array_to_string を使用
SELECT array_to_string(ARRAY[1,2,3], ',');
-- 結果: '1,2,3'
エラー3:日付フォーマットエラー
-- エラーになる例
SELECT '2025/14/09'::DATE;
-- ERROR: date/time field value out of range
-- 解決法:TO_DATE with format
SELECT TO_DATE('2025/14/09', 'YYYY/DD/MM');
-- 結果: 2025-09-14
安全な型変換のテクニック
1. TRY_CAST的な処理(PostgreSQL 15以降)
-- エラーを回避する変換
CREATE OR REPLACE FUNCTION safe_cast_int(text)
RETURNS INTEGER AS $$
BEGIN
RETURN $1::INTEGER;
EXCEPTION
WHEN OTHERS THEN
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
-- 使用例
SELECT safe_cast_int('123'); -- 123
SELECT safe_cast_int('abc'); -- NULL
2. 正規表現での事前チェック
-- 数値チェック
SELECT
CASE
WHEN value ~ '^\d+(\.\d+)?$' THEN value::NUMERIC
ELSE NULL
END AS safe_number
FROM data_table;
-- 日付チェック
SELECT
CASE
WHEN date_text ~ '^\d{4}-\d{2}-\d{2}$' THEN date_text::DATE
ELSE NULL
END AS safe_date
FROM data_table;
3. COALESCE でデフォルト値設定
SELECT
COALESCE(
NULLIF(price_text, '')::NUMERIC,
0
) AS price
FROM products;
パフォーマンスを考慮した型変換

インデックスへの影響
悪い例:インデックスが使われない
-- user_id にインデックスがあっても使われない
SELECT * FROM users WHERE user_id::TEXT = '123';
-- created_at にインデックスがあっても使われない
SELECT * FROM orders WHERE created_at::DATE = '2025-09-14';
良い例:インデックスを活用
-- 比較する値の方を変換
SELECT * FROM users WHERE user_id = '123'::INTEGER;
-- 範囲検索を使用
SELECT * FROM orders
WHERE created_at >= '2025-09-14'::TIMESTAMP
AND created_at < '2025-09-15'::TIMESTAMP;
大量データの型変換
バッチ処理での型変換:
-- 新しいカラムを追加して段階的に移行
ALTER TABLE products ADD COLUMN price_numeric NUMERIC;
-- バッチで更新
UPDATE products
SET price_numeric = price_text::NUMERIC
WHERE price_text ~ '^\d+(\.\d+)?$'
AND price_numeric IS NULL
LIMIT 1000;
-- 確認後、カラムを入れ替え
ALTER TABLE products RENAME COLUMN price_text TO price_text_old;
ALTER TABLE products RENAME COLUMN price_numeric TO price;
実践的な使用例
CSVインポート後のデータ整形
-- CSVからインポートしたテーブル(全カラムTEXT型)
CREATE TABLE import_temp (
user_id TEXT,
name TEXT,
age TEXT,
salary TEXT,
hire_date TEXT,
is_active TEXT
);
-- 適切な型のテーブルに変換して挿入
INSERT INTO users (user_id, name, age, salary, hire_date, is_active)
SELECT
user_id::INTEGER,
name,
NULLIF(age, '')::INTEGER,
REPLACE(REPLACE(salary, ',', ''), '円', '')::NUMERIC,
TO_DATE(hire_date, 'YYYY/MM/DD'),
CASE
WHEN is_active = '有効' THEN TRUE
WHEN is_active = '無効' THEN FALSE
ELSE NULL
END
FROM import_temp
WHERE user_id ~ '^\d+$'; -- 数値のみ処理
レポート用のフォーマット変換
-- 売上レポート用のフォーマット済みデータ
SELECT
TO_CHAR(sale_date, 'YYYY年MM月') AS 年月,
product_name AS 商品名,
TO_CHAR(quantity, 'FM999,999') AS 販売数,
TO_CHAR(price, 'FM999,999,999円') AS 単価,
TO_CHAR(quantity * price, 'FM999,999,999円') AS 売上金額,
TO_CHAR(
(quantity * price::NUMERIC) /
SUM(quantity * price) OVER (PARTITION BY TO_CHAR(sale_date, 'YYYY-MM')) * 100,
'FM990.0%'
) AS 売上構成比
FROM sales
ORDER BY sale_date, product_name;
まとめ:型変換マスターへの道
PostgreSQLの型変換について、重要なポイントをまとめます:
基本の3つの方法:
- 🔤 CAST関数 – 標準SQL準拠で可読性高い
- ⚡ ::演算子 – PostgreSQL独自だが簡潔
- 📝 変換関数 – TO_CHAR、TO_DATE等で細かい制御
実践のコツ:
- 明示的な型変換を心がける
- エラー処理を考慮した安全な変換
- インデックスへの影響を意識
- 正規表現で事前チェック
よく使うパターン:
- 文字列↔数値:計算や集計で必須
- 日付↔文字列:レポート作成で活躍
- JSON操作:モダンなアプリで重要
トラブル回避:
- CASE文で条件分岐
- COALESCEでNULL対策
- 正規表現で妥当性チェック
型変換は地味ですが、データベース操作の基礎中の基礎です。 この記事で紹介したテクニックを使いこなせば、どんなデータ形式の課題も解決できるようになります。
エラーメッセージに怯えることなく、自信を持ってSQLを書けるようになりましょう!
コメント