なんでそもそも比較や型変換が必要なの?例えば、テーブルに"42"って文字列があって、それを数値の42と比べたいとする。一見同じに見えるけど、DBにとっては全然違うものなんだ。PostgreSQLは自動で「君が何をしたいか」なんて推測してくれないし、型の比較の仕組みを知らないと、変な結果になったりエラーになったりするよ。
変換も同じ。時々、テキストを数値に変換して「いくつあるか」数えたいこともあるし、逆に数値をキレイな文字列で表示したいこともある。日付を"01.01.2025"みたいな形で出したい時もあるし、ユーザーにとってその方が見やすいよね。
他にも例を挙げると、正確な値はNUMERICで保存してるけど、科学計算にはFLOATを使いたい時とか。こういう時は明示的な変換が必須なんだ。
でも安心して!PostgreSQLはこういうの得意だから。柔軟で分かりやすいツールが揃ってる。大事なのは「どう使うか」を知ることと、ちょっとだけ中身を覗く勇気。じゃあ、やってみよう!
データ型の比較
PostgreSQLは賢いから、例えばINTEGERとNUMERICを比べる時は、ちゃんと共通の型に変換して比較してくれる。どっちも数値だし、これは普通のこと。
でも、文字列とブール値(TEXTとBOOLEAN)を比べようとすると、DBは「何がしたいの?」ってなる。全然違う型だから、PostgreSQLはエラーを返す。同じように、"42"って文字列と42って数値を、明示的に「文字列を数値に変換してね」って言わずに比べると、やっぱりエラーになる。
実際どうなるか見てみよう。これはエラーになる例:
SELECT '42' = 42; -- エラー!文字列と数値は変換しないと比較できない
こう書けばちゃんと動く:
SELECT '42'::INTEGER = 42; -- TRUE
ここではっきり「まず'42'を数値にしてね」って伝えてる。これが::型ってシンタックス。PostgreSQLは、ちゃんと明示してくれるのが好きなんだ。
数値型の比較
数値型(INTEGER、NUMERIC、REAL)はだいたい互換性があるから、特に問題なく比較できる:
SELECT 42 = 42.0; -- TRUE
SELECT 42::REAL = 42.0; -- TRUE
SELECT 42.0::NUMERIC = 42; -- TRUE
でもREALみたいな浮動小数点数は注意。精度の問題で、思わぬ動きをすることがある。例えば:
SELECT 0.1 + 0.2 = 0.3; -- FALSE
これ、プログラミング界隈で有名な謎だよね。ここでは、コンピュータのメモリで小数をどう保存してるかのせいで、FALSEになる。
テキスト型の比較
テキスト型を扱う時は、CHAR、VARCHAR、TEXTを比較できる。PostgreSQLが自動で互換性のある型に変換してくれるから:
SELECT 'Hello' = 'Hello'::TEXT; -- TRUE
SELECT 'World'::CHAR(5) = 'World'::VARCHAR; -- TRUE
CHAR(n)の文字数には注意。指定した長さより短いと、PostgreSQLがスペースで埋めてくれる。
データ型の変換
PostgreSQLはいくつかの型変換方法を用意してる。ここでは2つのメインなやり方を紹介:
方法1: 明示的な変換(CAST)
CAST演算子で、どの型に変換したいか指定できる。例:
SELECT CAST('42' AS INTEGER); -- 文字列'42'を数値42に変換
SQLコードを読みやすくしたい時に便利だよ。
方法2: ショートカット記法(::)
PostgreSQLは型変換のための別のシンタックス::も用意してる。意味は同じだけど、もっと短く書ける:
SELECT '42'::INTEGER; -- CAST('42' AS INTEGER)と同じ
自動変換
多くの場合、PostgreSQLは自動で型変換してくれる。例えば、文字列フィールドで数値を使う時:
SELECT '42' = 42::TEXT; -- TRUE
でも、自動変換に頼りすぎるのは危険。他の開発者が予想しない動きになることもある。特に日付と文字列の変換は、明示的にやった方がいいよ。
いろんなデータ型変換の例
数値からテキストへの変換
メッセージを作る時など、数値をテキストに変換したいことがある:
SELECT 42::TEXT; -- 数値42を文字列'42'に変換
SELECT 3.14::TEXT; -- 数値3.14を文字列'3.14'に変換
テキストから数値への変換
文字列が正しい数値なら、数値型に変換できる:
SELECT '123'::INTEGER; -- 文字列'123'を数値123に変換
SELECT '3.14'::FLOAT; -- 文字列'3.14'を数値3.14に変換
でも、変換できないテキストだとどうなる?例えば:
SELECT 'Hello'::INTEGER; -- エラー: 'Hello'は数値に変換できない
こういうエラーを避けたい時は、TRY_CAST()(PostgreSQL 14以降)や、事前にデータをチェックするのがオススメ。
日付とテキストの変換
日付の変換にはTO_CHAR()やTO_DATE()関数を使う:
SELECT TO_CHAR(CURRENT_DATE, 'YYYY-MM-DD'); -- 日付を文字列に変換
SELECT TO_DATE('2023-10-25', 'YYYY-MM-DD'); -- 文字列を日付に変換
BOOLEANとテキストの変換
論理型BOOLEANも文字列に変換できる:
SELECT TRUE::TEXT; -- 'true'
SELECT FALSE::TEXT; -- 'false'
逆もできる:
SELECT 'true'::BOOLEAN; -- TRUE
SELECT 'false'::BOOLEAN; -- FALSE
'yes'や'no'みたいな文字列は自動で変換されないから注意。
実践:全部リアルな例でやってみよう
いろんなデータ型を使ったテーブルを作ってみる:
| id | number_as_text - TEXT | number_as_integer - INTEGER | date_as_text - TEXT | actual_date - DATE |
|---|---|---|---|---|
| 1 | 42 | 42 | 2023-10-25 | 2023-10-25 |
| 2 | 3.14 | NULL | 2023-10-24 | NULL |
| 3 | Hello | 123 | NULL | NULL |
じゃあ、変換操作をやってみよう:
-- テキストを数値に変換
SELECT number_as_text::INTEGER FROM data_types_demo WHERE number_as_text = '42';
-- 日付をテキストに変換
SELECT TO_CHAR(actual_date, 'DD/MM/YYYY') FROM data_types_demo;
-- 文字列を日付に変換
SELECT TO_DATE(date_as_text, 'YYYY-MM-DD') FROM data_types_demo;
データ変換でよくあるミス
よくあるミスはこんな感じ:
- 期待したフォーマットじゃないデータを変換しようとする(例:
'Hello'をINTEGERに)。 - 浮動小数点数の丸めや精度の問題。
- 日付変換時のフォーマットミス。
ミスを防ぐには:
- 変換前に必ずデータをチェックする。
- エラー処理用の関数(
TRY_CASTやCASE)を使う。 - 日付変換時はフォーマットを明示する。
-- 変換前にデータをチェック
SELECT
CASE
WHEN number_as_text ~ '^\d+$' THEN number_as_text::INTEGER
ELSE NULL
END AS safe_integer
FROM data_types_demo;
このやり方で、クエリを予想外のトラブルから守ろう!
ここまでで、PostgreSQLでデータ型の比較と変換の基本スキルはバッチリ。あとは実践あるのみ!また次のレクチャーで会おう!
GO TO FULL VERSION