LoginSignup
1
0
はじめての記事投稿

json型カラムがあるテーブルをUNIONしたかった

Posted at

はじめに

json型カラムがあるテーブル同士をUNIONで結合したかったときのお話です。

SQLエラー発生

json型カラムがあるテーブルをUNIONで結合しようとしたらエラーになってしまいました。
等価演算がないよ、っていわれてる :rolling_eyes:

SELECT id, json_contents FROM hoge 
UNION
SELECT id, json_contents FROM fuga;
SQLエラー [42883]: ERROR: could not identify an equality operator for type json

回避方法

1. jsonb型にキャストする

json型カラムを、等価演算が使える「jsonb型」にキャストしたらエラーが消えました…!

ただしjsonb型が利用できるのはPostgreSQL9.4以上です。
それ以前のバージョンはtext型にキャストでいけるっぽい(すみません、未確認です)。

SELECT id, json_contents::jsonb FROM hoge 
UNION
SELECT id, json_contents::jsonb FROM fuga;

2. UNION ALL使う

UNIONを、等価演算しないUNION ALLに変えたらエラーが消えました…!

ただし、重複行を除いた結果を抽出したい場合はこの方法は使えません。
重複がないことが自明なテーブル同士を結合する or 重複したところで別に…という場合は、レコードチェックして重複を除く処理がなくなるぶんパフォーマンス的に優位な、UNION ALLを使うのがよいですね。

SELECT id, json_contents FROM hoge 
UNION ALL
SELECT id, json_contents FROM fuga;

さいごに

あらためてUNIONUNION ALLの違い、json型について確認です。

UNION と UNION ALL の違いは、重複行の扱いです。 UNION は、重複行を除外します。対して、UNION ALL は重複行を許します。 そのため、重複行を含むテーブルに対しての UNION と UNION ALL では、取得結果が変わります。
(引用元:【SQL】UNION、UNION ALLの使い方 - ITを分かりやすく解説

表9-1に示されている標準の比較演算子がjsonbで利用可能ですが、jsonではそうではありません。
(引用元:JSON関数と演算子 - PostgreSQL 9.4.5文書

結局、重複行チェックのため裏で等価演算を実行している部隊(UNION)に対して、等価演算が使えないやつ(json型)を派遣してしまったゆえ、起きた悲劇であった :expressionless:
…というオチでした。

参考

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0