CodeGym /コース /SQL SELF /データ型の比較と変換

データ型の比較と変換

SQL SELF
レベル 16 , レッスン 3
使用可能

なんでそもそも比較や型変換が必要なの?例えば、テーブルに"42"って文字列があって、それを数値の42と比べたいとする。一見同じに見えるけど、DBにとっては全然違うものなんだ。PostgreSQLは自動で「君が何をしたいか」なんて推測してくれないし、型の比較の仕組みを知らないと、変な結果になったりエラーになったりするよ。

変換も同じ。時々、テキストを数値に変換して「いくつあるか」数えたいこともあるし、逆に数値をキレイな文字列で表示したいこともある。日付を"01.01.2025"みたいな形で出したい時もあるし、ユーザーにとってその方が見やすいよね。

他にも例を挙げると、正確な値はNUMERICで保存してるけど、科学計算にはFLOATを使いたい時とか。こういう時は明示的な変換が必須なんだ。

でも安心して!PostgreSQLはこういうの得意だから。柔軟で分かりやすいツールが揃ってる。大事なのは「どう使うか」を知ることと、ちょっとだけ中身を覗く勇気。じゃあ、やってみよう!

データ型の比較

PostgreSQLは賢いから、例えばINTEGERNUMERICを比べる時は、ちゃんと共通の型に変換して比較してくれる。どっちも数値だし、これは普通のこと。

でも、文字列とブール値(TEXTBOOLEAN)を比べようとすると、DBは「何がしたいの?」ってなる。全然違う型だから、PostgreSQLはエラーを返す。同じように、"42"って文字列と42って数値を、明示的に「文字列を数値に変換してね」って言わずに比べると、やっぱりエラーになる。

実際どうなるか見てみよう。これはエラーになる例:

SELECT '42' = 42; -- エラー!文字列と数値は変換しないと比較できない

こう書けばちゃんと動く:

SELECT '42'::INTEGER = 42; -- TRUE

ここではっきり「まず'42'を数値にしてね」って伝えてる。これが::型ってシンタックス。PostgreSQLは、ちゃんと明示してくれるのが好きなんだ。

数値型の比較

数値型(INTEGERNUMERICREAL)はだいたい互換性があるから、特に問題なく比較できる:

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になる。

テキスト型の比較

テキスト型を扱う時は、CHARVARCHARTEXTを比較できる。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;

データ変換でよくあるミス

よくあるミスはこんな感じ:

  1. 期待したフォーマットじゃないデータを変換しようとする(例:'Hello'INTEGERに)。
  2. 浮動小数点数の丸めや精度の問題。
  3. 日付変換時のフォーマットミス。

ミスを防ぐには:

  • 変換前に必ずデータをチェックする。
  • エラー処理用の関数(TRY_CASTCASE)を使う。
  • 日付変換時はフォーマットを明示する。
-- 変換前にデータをチェック
SELECT 
    CASE 
        WHEN number_as_text ~ '^\d+$' THEN number_as_text::INTEGER
        ELSE NULL
    END AS safe_integer
FROM data_types_demo;

このやり方で、クエリを予想外のトラブルから守ろう!

ここまでで、PostgreSQLでデータ型の比較と変換の基本スキルはバッチリ。あとは実践あるのみ!また次のレクチャーで会おう!

コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION