PostgreSQLでunionした時に以下のような型が異なるエラーが出た場合の解決方法を解説します。
「UNION types character varying and bigint cannot be matched」
サンプルのテーブル作成
解説するために、以下のテーブルとデータを用意しておきます。
table_aのpopulationの方はbigintでtable_bのpopulationの方はvarcharにしています。
-- table_a作成
create table table_a(id int, city varchar, population bigint);
-- table_aにサンプルデータ挿入
insert
into table_a(id, city, population)
values
(1, 'A市', 832),
(2, 'B市', 333),
(3, 'C市', 111);
-- table_b作成
create table table_b(id int, city varchar, population varchar);
-- table_bにサンプルデータ挿入
insert
into table_b(id, city, population)
values
(1, 'D市', '732'),
(2, 'E市', '133'),
(3, 'F市', '311');
原因
先ほど作成したtable_aとtable_bの取得結果をUNIONでまとめて取得してみます。
-- table_aとtable_bからcityとpopulationを選択して、結果を一つにまとめる
select
city
, population
from
table_a
union
select
city
, population
from
table_b;
このsqlを実行すると型が異なる旨のこのようなエラーが表示されます。UNION types bigint and character varying cannot be matched
このエラーの原因はtable_aとtable_bのpopulationの型カテゴリが異なることです。table_aのpopulationの型カテゴリは数値型ですが、table_bの型カテゴリは文字型です。型カテゴリとはデータ型より大きな区分です。例えばintegerとbigintは両方とも数値型に分類されます。(詳細はこちら)
もしtable_bの型がbigintなどであれば、table_aとtable_bの型カテゴリが両方とも数値型でUNIONはエラーになりません。
実際にtable_bのpopulationカラムの型をbigintに変更して先ほどのUNIONを実行してみます。
-- table_bのpopulationカラムの型をbigintに変更
alter table table_b alter column population type bigint
using (population ::integer);
select
city
, population
from
table_a
union
select
city
, population
from
table_b;
正常に実行され、以下の結果を取得することが出来ました。
解決方法
解決方法はUNIONする前のそれぞれの結果のカラムの型カテゴリを揃えることです。
先ほどtable_bのpopulationカラムの型をbigintに変更した場合は元のvarcharに戻しておきます。
-- table_bのpopulationカラムの型varcharに戻す
alter table table_b alter column population type varchar
using (population ::varchar);
UNIONするときに型を揃えるために、キャストして型変換をします。
select
city
, population
from
table_a
union
select
city
, population::int -- integer型にキャスト
from
table_b;
まとめ
- 型カテゴリを揃えるためにキャストを行う
- UNIONするときはカラムの型カテゴリを揃える必要がある