1つの列に配列があるテーブルがありますが、テキスト形式で保存されています:
mytable
id ids
-- -------
1 '[3,4]'
2 '[3,5]'
3 '[3]'
etc ...
列の配列要素として値 5 を持つすべてのレコードを検索したいと考えていids
ます。
「string to array」関数を使用[
し、関数でシンボルを削除することでこれを達成しようとしましtranslate
たが、方法が見つかりませんでした。
1つの列に配列があるテーブルがありますが、テキスト形式で保存されています:
mytable
id ids
-- -------
1 '[3,4]'
2 '[3,5]'
3 '[3]'
etc ...
列の配列要素として値 5 を持つすべてのレコードを検索したいと考えていids
ます。
「string to array」関数を使用[
し、関数でシンボルを削除することでこれを達成しようとしましtranslate
たが、方法が見つかりませんでした。
これを行うことができます:http://www.sqlfiddle.com/#!1/5c148/12
select *
from tbl
where translate(ids, '[]','{}')::int[] && array[5];
出力:
| ID | IDS |
--------------
| 2 | [3,5] |
bool_or も使用できます: http://www.sqlfiddle.com/#!1/5c148/11
with a as
(
select id, unnest(translate(ids, '[]','{}')::int[]) as elem
from tbl
)
select id
from a
group by id
having bool_or(elem = 5);
元の要素を表示するには:
with a as
(
select id, unnest(translate(ids, '[]','{}')::int[]) as elem
from tbl
)
select id, '[' || array_to_string(array_agg(elem), ',') || ']' as ids
from a
group by id
having bool_or(elem = 5);
出力:
| ID | IDS |
--------------
| 2 | [3,5] |
Postgresql DDL はアトミックです。プロジェクトでまだ遅くない場合は、文字列型の配列を実際の配列に構造化してください: http://www.sqlfiddle.com/#!1/6e18c/2
alter table tbl
add column id_array int[];
update tbl set id_array = translate(ids,'[]','{}')::int[];
alter table tbl drop column ids;
クエリ:
select *
from tbl
where id_array && array[5]
出力:
| ID | ID_ARRAY |
-----------------
| 2 | 3,5 |
contains 演算子も使用できます: http://www.sqlfiddle.com/#!1/6e18c/6
select *
from tbl
where id_array @> array[5];
私は構文を好み&&
ますが、それは交差を直接暗示しています。2つのセットの間に交差があるかどうかを検出していることを反映しています(配列はセットです)
http://www.postgresql.org/docs/8.2/static/functions-array.html
配列の文字列表現を少し異なる方法で保存する場合は、次のようにarray of integer
直接キャストできます。
INSERT INTO mytable
VALUES
(1, '{3,4}')
,(2, '{3,5}')
,(3, '{3}');
SELECT id, ids::int[]
FROM mytable;
それ以外の場合は、もう 1 つの手順を実行する必要があります。
SELECT (translate(ids, '[]','{}'))::int[]
FROM mytable
そもそも列を配列型にすることを検討します。
どちらの方法でも、次のように行を見つけることができます。
SELECT id, ids
FROM (
SELECT id, ids, unnest(ids::int[]) AS elem
FROM mytable
) x
WHERE elem = 5