配列は、タグや番号、役割、好みみたいに、1つのカラムに複数の値を保存したいときによく使うよね。でも、配列の中に欲しい値が入ってるか、逆に全部の要素が特定の条件を満たしてるか、どうやって調べる?PostgreSQLには、そういうチェックに便利なANY、ALL、array_contains()があるんだ。それぞれ順番に見ていこう!
ANYって何?
例えば、いくつかの値(商品IDや電話番号、趣味リストとか)が入った配列があるとする。よく「この配列に特定の値があるか?」って調べたいことがあるよね。そこで登場するのがANYオペレーター。これを使うと、「探してるやつ」が配列に入ってるかチェックできる。
ANYの書き方
SELECT *
FROM your_table
WHERE value = ANY(array_column);
ここで:
array_column— チェックしたい配列カラム。value— 配列の中で探したい値。
ANYの使い方例
例えば、studentsっていうテーブルがあって、こんな構造だとする:
| id | name | hobbies |
|---|---|---|
| 1 | Otto | {読書, 水泳, チェス} |
| 2 | Eva | {音楽, 読書, スポーツ} |
| 3 | Alex | {絵描き, 音楽} |
| 4 | Maria | {チェス, サッカー} |
趣味の中に水泳がある学生を探したいとき、クエリはこうなる:
SELECT *
FROM students
WHERE '水泳' = ANY(hobbies);
結果:
| id | name | hobbies |
|---|---|---|
| 1 | Otto | {読書, 水泳, チェス} |
ざっくり言うと、ANYは「この配列にこの値ある?」ってチェックしてくれるやつ。
信じるけど全部チェック!ALLを使う
今度は逆パターン。全部の配列要素が特定のルールを満たしてるか確かめたいとき。そんなときはPostgreSQLのALLオペレーターが便利。これを使うと、全部の要素が例えば指定した値と同じか、ある数字より大きいか、みたいな論理条件をまとめてチェックできる。
ALLの書き方
SELECT *
FROM your_table
WHERE value < ALL(array_column);
ここで:
array_column— チェックしたい配列カラム。value < ALL(...)は、全部の要素がその値より大きいって意味。
さっきのstudentsテーブルに戻るよ。例えば、趣味が全部「読書」な学生を探したいとき:
SELECT *
FROM students
WHERE '読書' = ALL(hobbies);
結果は空っぽ。だって誰も全部の趣味が「読書」じゃないからね。もっと分かりやすい(ちゃんと動く)例として、数字データで考えてみよう。
例えば、ordersってテーブルがあるとする:
| id | customer | prices |
|---|---|---|
| 1 | Otto | {100, 200, 300} |
| 2 | Eva | {50, 60, 70} |
| 3 | Alex | {500, 600, 700} |
全部の値段が400より安い注文を探す:
SELECT *
FROM orders
WHERE 400 > ALL(prices);
結果:
| id | customer | prices |
|---|---|---|
| 1 | Otto | {100, 200, 300} |
| 2 | Eva | {50, 60, 70} |
配列の中身で行をフィルタする
基本的な関数やオペレーターの使い方は分かったけど、実際どう使うの?いくつか例を見てみよう。
例1: 趣味に「音楽」が1つでもある学生を探す
元のテーブル:
| id | name | hobbies |
|---|---|---|
| 1 | Otto | {読書, 音楽, ランニング} |
| 2 | Eva | {絵描き, 水泳} |
| 3 | Maria | {音楽, ボクシング} |
| 4 | Alex | {サッカー, ボクシング, ボードゲーム} |
SELECT *
FROM students
WHERE '音楽' = ANY(hobbies);
結果:
| id | name | hobbies |
|---|---|---|
| 1 | Otto | {読書, 音楽, ランニング} |
| 3 | Maria | {音楽, ボクシング} |
例2: 全部の値段が100より高い注文を探す
元のテーブルorders:
| id | customer | prices |
|---|---|---|
| 1 | Otto | {150, 200, 300} |
| 2 | Eva | {50, 120, 130} |
| 3 | Maria | {200, 250, 100} |
| 4 | Alex | {110, 115, 120} |
SELECT *
FROM orders
WHERE 100 < ALL(prices);
結果:
| id | customer | prices |
|---|---|---|
| 1 | Otto | {150, 200, 300} |
| 4 | Alex | {110, 115, 120} |
よくあるミスとその回避法
配列でデータ検索するとき、特に気をつけたい落とし穴がいくつかあるよ。
ミス: ANYやALLの使い方を間違える。 例えば、オペレーターを逆にしちゃうと、思わぬ結果になることも。
-- 間違った例:
SELECT *
FROM students
WHERE hobbies = ANY('読書');
この例のミスは、hobbiesが配列で、'読書'が文字列なこと。ANYでチェックするのは配列の方で、逆じゃダメ。
ミス: 配列のインデックスは1から始まる(0じゃない) 他の関数で配列を使ったり、手動で要素を取り出すときは、PostgreSQLのこの仕様に注意しよう。
ミス: インデックスを作ってない 配列でANYやALLみたいな検索をよくやるなら、インデックスを作るとクエリがめっちゃ速くなるよ。
GO TO FULL VERSION