ショコラ
ポストグレスで配列を使うには?
ポストグレスの配列についてのまとめ。
もっさん先輩
配列を表現するには2つの方法がある。
シングルクォートで波括弧(ブレース)を囲んで配列を表現する方法
SELECT '{1,2,3}';
postgres=# SELECT '{1,2,3}';
?column?
----------
{1,2,3}
array と角括弧(ブラケット)を使って配列を表現する方法
SELECT array[1,2,3];
postgres=# SELECT array[1,2,3];
array
---------
{1,2,3}
(1 行)
テーブルを作成する。
CREATE TABLE num (
id TEXT PRIMARY KEY,
tags INTEGER[]
);
配列にインデックスを付ける。
CREATE INDEX idx_num_tags ON num USING GIN(tags);
配列をインサートする。
INSERT INTO num(id,tags) VALUES('001','{2,3,5,7,11,13,17,19}');
配列をインサートする。array も使えます。
INSERT INTO num(id,tags) VALUES('001',array[2,3,5,7,11,13,17,19]);
配列をアップデートする。
UPDATE num SET tags='{2,3,5,7,11,13,17,19,23,29,31,37,41,43,47}' WHERE id='001';
配列をアップデートする。array も使えます。
UPDATE num SET tags=array[2,3,5,7,11,13,17,19,23,29,31,37,41,43,47] WHERE id='001';
1つの値(19を含むもの)で配列を検索する。
SELECT * FROM num WHERE tags @> array[19];
postgres=# SELECT * FROM num WHERE tags @> array[19];
id | tags
-----+--------------------------------------------
001 | {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47}
(1 行)
複数の値(2と47を含むもの=AND)で配列を検索する。
SELECT * FROM num WHERE tags @> array[2,47];
postgres=# SELECT * FROM num WHERE tags @> array[2,47];
id | tags
-----+--------------------------------------------
001 | {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47}
(1 行)
複数の値(1または19を含むもの=OR)で配列を検索する。
SELECT * FROM num WHERE tags && array[1,19];
postgres=# SELECT * FROM num WHERE tags && array[1,19];
id | tags
-----+--------------------------------------------
001 | {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47}
(1 行)
副問い合わせで得た配列で配列を検索する。
SELECT * FROM num WHERE tags && (SELECT array[19]);
postgres=# SELECT * FROM num WHERE tags && (SELECT array[19]);
id | tags
-----+--------------------------------------------
001 | {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47}
(1 行)
ポイントは SELECT をただの丸括弧で囲むところです。
スカラーのカラム(?)を配列で検索する。ようするに「IN」。
SELECT * FROM num WHERE id = any(array['000','001','002']);
postgres=# SELECT * FROM num WHERE id = any(array['000','001','002']);
id | tags
-----+--------------------------------------------
001 | {2,3,5,7,11,13,17,19,23,29,31,37,41,43,47}
(1 行)
UNNEST関数で配列を行に展開する。
SELECT id,unnest(tags) FROM num;
postgres=# SELECT id,unnest(tags) FROM num;
id | unnest
-----+--------
001 | 2
001 | 3
001 | 5
001 | 7
001 | 11
001 | 13
001 | 17
001 | 19
001 | 23
001 | 29
001 | 31
001 | 37
001 | 41
001 | 43
001 | 47
(15 行)
UNNEST関数を使って join して取得する。
SELECT * FROM tag WHERE tag_id IN (SELECT unnest(tags::int[]) FROM num);
ARRAY_AGG関数を使って行から配列に変換する。ようするにUNNESTの逆。
SELECT array_agg(tag) FROM (SELECT unnest(tags) tag FROM num) tmp;
postgres=# SELECT array_agg(tag) FROM (SELECT UNNEST(tags) tag FROM num) tmp;
array_agg
--------------------------------------------------------------------------
{2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,21,23,29,31,33,37,47,51,53,59}
(1 行)
ARRAY_AGG関数を使って行から配列に変換する。DISTINCT で値を1つにする。
SELECT array_agg(DISTINCT tag) FROM (SELECT unnest(tags) tag FROM num) tmp;
postgres=# SELECT array_agg(DISTINCT tag) FROM (SELECT unnest(tags) tag FROM num) tmp;
array_agg
-----------------------------------------------------------
{2,3,5,7,11,13,17,19,21,23,29,31,33,37,41,43,47,51,53,59}
(1 行)
配列に1つの値を追加する。
select array_append('{1,2}',3);
postgres=# select array_append('{1,2}',3);
array_append
--------------
{1,2,3}
(1 行)
配列に配列を追加する。
select array_cat('{1,2}','{2,3,4}');
postgres=# select array_cat('{1,2}','{2,3,4}');
array_cat
-------------
{1,2,2,3,4}
(1 行)