4.1 データ型と型変換

以下を確認します。

  • 数値データ型: integer型、numeric型、real型
  • 文字列データ型: char型、varchar型、text型
  • 日付・時刻データ型: date型、time型、timestamp型
  • 型変換: 暗黙の変換、明示の変換(型キャスト)

数値データ型

各種数値データ型の列で構成されるtest_n表を作成して、データの格納状況と演算結果を確認します。

postgres=# CREATE TABLE test_n ( --数値データテーブルの作成
  c1 INTEGER,
  c2 NUMERIC,
  c3 NUMERIC(6, 2),
  c4 REAL
);
CREATE TABLE
postgres=# INSERT INTO test_n VALUES
  (123, 123, 123, 123), --整数の挿入
  (150.12, 150.12, 150.12, 150.12), --固定小数点数の挿入
  (3.1415926, 3.1415926, 3.1415926, 3.1415926); --浮動小数点数の挿入
INSERT 0 3
postgres=# SELECT * FROM test_n; --挿入結果の確認
 c1  |    c2     |   c3   |    c4
-----+-----------+--------+-----------
 123 |       123 | 123.00 |       123
 150 |    150.12 | 150.12 |    150.12
   3 | 3.1415926 |   3.14 | 3.1415925
(3 行)

postgres=# SELECT c1*3 AS "c1*3", c2*3 AS "c2*3", c3*3 AS "c3*3",
  c4*3 AS "c4*3" FROM test_n; --計算結果の確認
 c1*3 |   c2*3    |  c3*3  |       c4*3
------+-----------+--------+-------------------
  369 |       369 | 369.00 |               369
  450 |    450.36 | 450.36 | 450.3599853515625
    9 | 9.4247778 |   9.42 | 9.424777507781982
(3 行)

postgres=# DROP TABLE test_n; --テーブルの削除
DROP TABLE
postgres=#

integer型のc1列は整数のみ、numeric型のc2列は整数部と小数部を保持します。c3列はNUMERIC(6, 2)のように桁数を指定しているため、小数部は指定した桁数のみ保持します。float型のc4列は非常に大きい又は小さい数を保持できますが、誤差が生じる可能性があります。

文字列データ型

各種文字列データ型の列で構成されるtest_c表を作成して、データの格納状況を確認します。

postgres=# CREATE TABLE test_c ( --文字列データテーブルの作成
  c1 CHAR(5),
  c2 VARCHAR(5),
  c3 TEXT
);
CREATE TABLE
postgres=# INSERT INTO test_c VALUES
  ('A', 'A', 'A'), --1文字の挿入
  ('ABC', 'ABC', 'ABC'), --3文字の挿入
  ('ABCBC', 'ABCBC', 'ABCBC'); --5文字の挿入
INSERT 0 3
postgres=# SELECT * FROM test_c; --挿入結果の確認
  c1   |  c2   |  c3
-------+-------+-------
 A     | A     | A
 ABC   | ABC   | ABC
 ABCBC | ABCBC | ABCBC
(3 行)

postgres=# SELECT c1 FROM test_c WHERE c1 LIKE '% '; --char型末尾空白の確認
  c1
-------
 A
 ABC
(2 行)

postgres=# SELECT c2 FROM test_c WHERE c2 LIKE '% '; --varchar型末尾空白の確認
 c2
----
(0 行)

postgres=# SELECT c3 FROM test_c WHERE c3 LIKE '% '; --text型末尾空白の確認
 c3
----
(0 行)

postgres=# SELECT c1 FROM test_c WHERE c1 LIKE '%BC'; --char型末尾'BC'の検索
  c1
-------
 ABCBC
(1 行)

postgres=# SELECT c2 FROM test_c WHERE c2 LIKE '%BC'; --vatchar型末尾'BC'の検 索  c2
-------
 ABC
 ABCBC
(2 行)

postgres=# SELECT c3 FROM test_c WHERE c3 LIKE '%BC'; --text型末尾'BC'の検索
  c3
-------
 ABC
 ABCBC
(2 行)

postgres=# INSERT INTO test_c(c2) VALUES('ABCABC'); --エラー
ERROR:  値は型character varying(5)としては長すぎます
postgres=# INSERT INTO test_c(c3) VALUES('ABCABC'); --OK
INSERT 0 1
postgres=# DROP TABLE test_c; --テーブルの削除
DROP TABLE
postgres=#

char型のc1列、varchar型のc2列、text型のc3列には、一見同じように文字列が格納されていますが、LIKE述語を使って文字列の末尾部分を検索すると、c1列は長さが不足した部分が空白文字で埋められているのに対し、c2列とc3列には空白文字がないことを確認できます。また、c2列には5文字を超える文字列は格納できませんが、c3列には格納できます。

日付・時刻データ型

各種日付・時刻データ型の列で構成されるtest_d表を作成して、データの格納状況と演算結果を確認します。

postgres=# CREATE TABLE test_d ( --日付・時刻データテーブルの作成
  c1 TIMESTAMP,
  c2 DATE,
  c3 TIME
);
CREATE TABLE
postgres=# INSERT INTO test_d (c1) VALUES
  ('2024-04-01 10:30:00'), --2024年4月1日10時30分の挿入
  (CURRENT_TIMESTAMP); --現在の日時の挿入
INSERT 0 2
postgres=# UPDATE test_d SET c2 = c1, c3 = c1; --日時のコピー
UPDATE 2
postgres=# SELECT * FROM test_d; --挿入結果の確認
             c1             |     c2     |       c3
----------------------------+------------+-----------------
 2024-04-01 10:30:00        | 2024-04-01 | 10:30:00
 2024-06-17 18:11:47.732688 | 2024-06-17 | 18:11:47.732688
(2 行)

postgres=# SELECT CURRENT_TIMESTAMP - c1, CURRENT_DATE - c2, CURRENT_TIME - c3
  FROM test_d; --現在の日時との差分
        ?column?         | ?column? |      ?column?
-------------------------+----------+--------------------
 77 days 07:42:37.286432 |       77 | 07:42:37.286432+09
 00:00:49.553744         |        0 | 00:00:49.553744+09
(2 行)

postgres=# DROP TABLE test_d; -- テスト用テーブルの削除
DROP TABLE
postgres=#

timestamp型のc1列は日付と時刻の両方を保持します。date型のc2列は日付のみを保持します。time型のc3列は時刻のみを保持します。いずれの型も日時の差分を計算することができます。

型変換

数値データ型と文字列データ型について、暗黙の型変換と明示の型変換(型キャスト)を確認します。

postgres=# SELECT 10.5 / 3; --暗黙の変換
      ?column?
--------------------
 3.5000000000000000
(1 行)

postgres=# SELECT CAST(10.5 / 3 AS INTEGER); --型キャスト(1)
 int4
------
    4
(1 行)

postgres=# SELECT CAST(10.5 AS INTEGER) / 3; --型キャスト(2)
 ?column?
----------
        3
(1 行)

postgres=# SELECT 2 * '3.1415'; --エラー
ERROR:  "integer"型の入力構文が不正です: "3.1415"
行 1: SELECT 2 * '3.1415';
                 ^
postgres=# SELECT 2 * '3.1415'::NUMERIC; --型キャスト(3)
 ?column?
----------
   6.2830
(1 行)

postgres=# SELECT 2 * '3.1415'::NUMERIC(5, 2); --型キャスト(4)
 ?column?
----------
     6.28
(1 行)

postgres=#

暗黙の型変換は、できる限り計算結果の精度が保たれるように行われます。型キャスト(1)(2)は、型変換を行うタイミングの違いによって計算結果が異なることを確認しています。
数値データ型と文字列データ型の掛算はエラーになりますが、型キャスト(3)(4)のように文字列データ型を数値データ型に変換すれば掛算ができるようになります。