データ型を独学理解!ビジネスパーソンのためのSQL入門講座

プログラミングを勉強したことがある方にとっては、「データ型」はお馴染みの存在でしょう。
様々なプログラミング言語の入門書で登場します。

Google検索結果「プログラミング データ型」

当記事では、BigQueryをベースに、SQLで使うデータ型を解説します。
なお、他のデータベースでは多少の違いが存在します。
その場合は適宜読み替えてください。

データ型を理解しておくメリット4選

最初に、理解しておくメリットです。
クエリを沢山書いている内に体得できてしまうものですが、先に勉強しておいた方が効率的に会得できます。

  • エラー発生時や不具合の対応に強くなれる。
  • 関数を正しく取り扱えるようになる。
  • スキーマ、テーブル定義書を読み書きできるようになるための最初の一歩になる。
  • プログラミングを勉強する時にも知識を流用できる。

データ型とは?

まずは、Wikipediaの解説を見てみましょう。
SQL初心者にとっては難しい説明でしょうから、なんとなくの雰囲気だけ読み取っていただければOKです。

データ型(データがた、Data type)とは、コンピュータプログラミングや計算機科学において、属性を持つデータを分類し、その扱われ方をコンパイラやインタープリタに知らせるプログラム。単に型(かた、Type)とも言われる。

多くのプログラミング言語は、整数型・浮動小数点型・ブール型・文字型といった基本データ型を備えている。計算対象にされるデータは、しばしば値(value)と言われる。データ型は式内の値を制約して、関数への適用可能性や変数への代入可能性を定義する。データ型は、値の集合の概念と近似している。

https://ja.wikipedia.org/wiki/%E3%83%87%E3%83%BC%E3%82%BF%E5%9E%8B

BigQueryの公式リファレンス「データ型」でも説明されていますが、初心者の方には読みづらい内容でしょう。

簡単に言ってしまえば、このデータは数値ですよ、このデータは文字ですよ、といった属性のことです。
先に、BigQueryを使う上でどんなデータ型を取り扱うことになるかを見てみましょう。

BigQueryでよく使うデータ型10選

数値を取り扱う時のデータ型2つ

INT64

数値の中でも、整数を取り扱う時に使うデータ型です。
数量や価格などのボリュームを表す場面で使うのはもちろんですが、IDなどの連番にも使われます。
頻繁に使うことになるので、特に身近なデータ型です。

手打ちで入力する時は、「100」、「0」、「-10」のように、半角数字で入力します。

FLOAT64

数値の中でも、小数を取り扱う時に使うデータ型です。
平均値を算出した時にも登場するので、これも触れる機会は多いでしょう。

手打ちで入力する時は、「10.0」、「-0.123」のように、半角数字と「.」(半角ドット)で入力します。

文字を取り扱う時のデータ型1つ

STRING

文字列を取り扱う時は、このデータ型になるでしょう。
名称や文章などを表す場面で使われます。
これも特に身近なデータ型と言えるでしょう。

手打ちで入力する時は、どこからどこまでが文字列なのかを示すため、「’」(シングルクォーテーション)か「”」(ダブルクォーテーション)で囲む必要があります。
文字列の中で「’」「”」を使いたい時は、使っていない方の囲み文字を使う、あるいは、エスケープ処理と呼ばれる前処理を行う必要があります。
エスケープ処理とは、特殊な意味を持つ記号(今回は「’」と「”」で、文字列の始まりと終わりを意味する)を取り扱う時、特殊な意味を持たない文字としてその記号を使うように指定する処理方法のことで、「’」は「\’」、「”」は「\”」のように、「\」(半角バックスラッシュ)(環境によっては半角円マーク)を記号の前に付けて指定します。

SELECT
  'test 1',
  "test 2",
  'test "3"',
  "test '4'",
  'test \'5\'',
  "test \"6\""

上記のサンプルクエリでは、6つの文字列を出力できます。

文字列データを取り扱う時、初めて勉強する人のために特筆しておきたい言葉で、「空文字」(からもじ)というものがあります。
「文字」と言われて思い浮かぶのは、「A」などの具体的な文字や「あいうえお」といった文字列、文字が無いように見える文字であっても「 」(スペース)のような記号でしょう。
しかしSQLやプログラミングでは、「」のように文字が一文字もない状態の文字を取り扱うことができます。
文字列の長さが0の時、その文字データを「空文字」と言います。
STRING型を取り扱う時、空文字とNULLは別物になるので、取り扱いに注意しましょう。

もう1点、特筆するポイントとして、文字列の大小の話があります。
その文字列が辞書に掲載されたものと想像して、最初の方に登場する文字列の方が小さく、最後の方に登場する文字列の方が大きい、このような大小評価ルールがあります。
勉強を進めると繰り返し登場する話なので、まずは豆知識として覚えておきましょう。

日時を取り扱う時のデータ型4つ

DATE

日付を取り扱う時のデータ型です。
ビッグデータを取り扱う際、日付毎に集計する場面が多く発生します。
特に身近なデータ型の一つです。

手打ちで入力する時は、たとえば「DATE(“2023-01-01”)」のように入力します。
「/」(半角スラッシュ)で年月日を区切るフォーマットに慣れ親しんでいるので違和感があるかもしれませんが、SQLで日付を扱う時には「-」(半角ハイフン)を使うものとして覚えてしまいましょう。

SELECT DATE("2023-01-01")

TIME

時刻を取り扱う時のデータ型です。
DATEとセットで覚えてしまって良いですが、日付を含まず時分秒のデータとなるため、DATEと比べると利用機会は少ないです。

DATETIME

日時を取り扱う時のデータ型です。
DATEとTIMEを合体させたもの、と理解しておいてOKです。
ビッグデータを取り扱う以上、登録日時や更新日時など、様々な場面で日時データを取り扱うことになります。
ぜひ覚えておきましょう。

手打ちで入力する時は、たとえば「DATETIME(“2023-01-01 01:23:45.678901”)」のように入力します。

SELECT DATETIME("2023-01-01 01:23:45.678901")

TIMESTAMP

日時を取り扱う時のデータ型ですが、TIMESTAMPでは地域情報(タイムゾーン)も併せて取り扱えます。
グローバルな日時を取り扱う時に使うデータ型です。
ビジネス利用する際、システム側がDATETIMEでなくTIMESTAMPを採用していれば、触れる機会が多いでしょう。
取り扱う際は、世界標準時間で取り扱っているのか、日本時間で取り扱っているのか、注意して操作する必要があります。

手打ちで入力する時は、たとえば「TIMESTAMP(“2023-01-01 01:23:45.678901”, “UTC”)」のように入力します。
タイムゾーンの指定を間違えると思わぬ日時になってしまうため、入力には注意が必要です。
また、タイムゾーンの指定には色々な指定方法があるため、チームメンバーの間で統一するのが良いでしょう。

SELECT
  DATETIME("2023-01-01 01:23:45.678901"),
  TIMESTAMP("2023-01-01 01:23:45.678901", "UTC"),
  TIMESTAMP("2023-01-01 01:23:45.678901", "Asia/Tokyo"),
  TIMESTAMP("2023-01-01 01:23:45.678901", "Japan")

YES/NOを取り扱う時のデータ型1つ

BOOL

二値データを取り扱う時のデータ型です。
真/偽、といった言い方の方がしっくりくる方もいらっしゃるでしょう。
BigQueryではTRUE/FALSEで表現されています。
中級者の方の中には、このデータ型にあまり触れずに習得された方もいらっしゃいますが、実はとても大事なデータ型なので、意識的にしっかり習得し、使いこなせるようになることをおすすめします。

条件式を勉強する時にも登場しますが、その時、このデータ型が重要な理由を感じていただけることでしょう。

条件式を解説する記事へのリンクを設置予定

手打ちで入力する時は、「TRUE」、「FALSE」のように入力します。

SELECT
  TRUE,
  FALSE

余談ですが、BOOL型を積極的に利用する現場では、BOOL型のカラムの名前を「is_valid」、「is_deleted」のように「is_」から始まる名前を使うのが主流です。
これは、TRUEとFALSE、どちらの値の時にどんな意味を指すかがカラム名から分かるからです。
たとえば「delete_status」というカラム名の時、TRUEだったらdeleteなのか、FALSEだったらdeleteなのか分かりづらいところ、「is_deleted」というカラム名であればTRUEがdeleteだと伝わるメリットがあります。

データの集合を取り扱う時のデータ型2つ

よく使うデータ型として紹介しますが、初心者の方が取り扱うにはハードルが高いです。
将来勉強するものとして覚えつつ、理解は後回ししておきましょう。

ARRAY

いわゆる、配列型です。
このデータ型を使うことで、1レコード1カラムの中に複数のレコードを格納した状況を実現できます。
取り扱いが難しいため、初心者の内は忘れてしまって構いません。

STRUCT

いわゆる、構造体です。
このデータ型を使うことで、1レコード1カラムの中に複数のカラムを格納した状況を実現できます。
こちらも取り扱いが難しいため、初心者の内は忘れてしまって構いません。
GoogleAnalyticsのデータなど、構造が整理された状態でデータを取り扱う際、目にすることがあるでしょう。

BigQueryで使える他の便利なデータ型2選

初心者には難しいデータ型ですが、便利なデータ型の例を紹介します。
使うことになるまで覚える必要はないので、こんなものもある、程度でご覧ください。

その他の便利なデータ型その1

JSON

JSONと呼ばれるデータ構造を取り扱えるようになります。
要素の増減を簡単に操作できるため、システム側からそのままデータを連携される環境でデータ操作する場面では、頻繁に使うことになるでしょう。

その他の便利なデータ型その2

GEOGRAPHY

緯度経度を取り扱うデータ型です。
距離計算などに使えるため、地理的なデータ利活用を行う場面では便利です。

データ型を変換する方法

CAST、SAFE_CASTを使った変換

BigQueryを使う中で、最も身近な変換方法でしょう。

SELECT
  1 AS sample_int,
  CAST(1 AS STRING) AS sample_string,
  CAST(1 AS FLOAT64) AS sample_float

「CAST(変換したい元の値 AS 変換したいデータ型)」と書くことで、目的のデータ型に変換することができます。

しかし、変換することができないような組み合わせの時はエラーになります。

SELECT CAST(1 AS TIMESTAMP) AS sample_error
Invalid cast from INT64 to TIMESTAMP at [1:13]

エラーをとりあえず回避したい時には、CASTではなくSAFE_CASTを使うこともあります。

SELECT SAFE_CAST(1 AS TIMESTAMP) AS sample_error

SAFE_CASTを使うことで、変換時にエラーになるレコードはNULLで算出してくれます。

SAFE_CASTを使っておけばエラーにならないため、CASTを一切使わない人も存在します。
しかしそれは、SAFE_CASTでなくCASTを使うメリット、想定外のデータを取り扱おうとした時にエラーになって止めてくれる利点を放棄してしまうことになります。
筆者としては、可能な限りSAFE_CASTを使わず、明確な根拠・理由がある時に限るようにすることをおすすめします。

他の関数を使っての変換

CAST、SAFE_CASTは汎用性が高く使いやすいですが、他にも変換のための関数が存在します。

SELECT
  "2023-01-01" AS sample_string,
  CAST("2023-01-01" AS DATE) AS sample_date_cast_version,
  PARSE_DATE("%Y-%m-%d", "2023-01-01") AS sample_date_parse_date_version

ちなみに、CASTでDATE型に変換する時、適切なフォーマットになっている必要があるため、「-」(半角ハイフン)が「/」(半角スラッシュ)になるとエラーになってしまいます。

SELECT
  "2023/01/01" AS sample_string,
  CAST("2023/01/01" AS DATE) AS sample_date_cast_version
Invalid date: '2023/01/01'

PARSE_DATEという関数では、文字列のフォーマットを指定してDATE型に変換してくれるので、このケースでも問題なく変換できます。

SELECT
  "2023/01/01" AS sample_string,
  PARSE_DATE("%Y/%m/%d", "2023/01/01") AS sample_date_parse_date_version

文字列のフォーマットを指定できるので、日本語で「年月日」と表記されていても対応できます。

SELECT
  "2023年01月01日" AS sample_string,
  PARSE_DATE("%Y年%m月%d日", "2023年01月01日") AS sample_date_parse_date_version

STRING型をDATE型に変換するケースでは、CASTでなくPARSE_DATEを使うことをおすすめします。
対応できるケースが多いことも理由ではありますが、チームメンバーがクエリを読む場面などでは、意図通りの変換ができていることを保証できるためです。
日付の形式は疑いだせば思わぬフォーマット(例えばアメリカ式やイギリス式のフォーマットなど)があり得るものです。

暗黙的変換

BigQueryが勝手にデータ型を解釈して変換してくれる場面があります。

SELECT
  "2023-01-01" AS sample_string,
  DATE("2023-01-23") AS sample_date,
  DATE_DIFF("2023-01-01", DATE("2023-01-23"), DAY)

DATE_DIFFという関数では、2つの日付の間の日数を算出してくれます。
今回のサンプルクエリでは、あえてSTRING型とDATE型を混在させましたが、実行してみると、BigQueryが日付として解釈して問題なく算出されます。

自身が変換処理を指定していないのに変わる場面がある、と覚えておきましょう。

計算式を使っての変換

ちょっとテクニカルに感じる変換方法ですが、計算式(演算子)を使ってデータ型を変換させる方法があります。
実際に見てみましょう。

SELECT
  1, -- INT64型
  1 * 1.0, -- FLOAT64型 -- 「* 1.0」で小数を伴った計算を行っているため、FLOAT64型に変換される。
  1 || "", -- STRING型 -- 「|| ""」で空文字を付け加える処理を行っているため、STRING型に変換される。

数値に1を掛けても元の数値のままですが、整数の1でなく小数の1.0を掛けることで、BigQueryが小数型と判断して小数に変換してくれます。
数値に文字を付け加えると、暗黙的変換でBigQueryが数値を文字として解釈して変換してくれますが、空文字を付け加えることで余計な文字を付け加えることなく、元の数値のまま文字列型に変換してくれます。

これらの変換はやや特殊で、クエリを読んだ人が一瞬戸惑ってしまいます。
読み手が「もしかしてタイピングミスなんじゃないか」と頭によぎってしまうからです。
なので、使う機会は無いでしょう。
こういった変換をする人もいる、という知識だけ、頭に入れておきましょう。

振り返り

お疲れさまでした。
慣れてしまえば簡単なので、ついつい勉強では素通りしてしまうのですが、急がば回れ、ちゃんと勉強しておくと後々の習得が楽になります。

なお、今回勉強したデータ型をもう一歩踏み込んで理解するためには、「NULL」について勉強する必要があります。
別記事で紹介しているので、ぜひそちらもご一読ください。

NULLを解説する記事へのリンクを設置予定