SQLの SELECT * FROM TABLE WHERE FIELD IN (SELECT FIELD1 FROM TABLE2 WHERE FIELD1 >= 1) のように、WHERE 句の中で副問い合わせを使用するケース(サブクエリ)について解説します。
🧐 WHERE句での副問い合わせ(条件抽出)
SQLで WHERE 句の中で副問い合わせを使用する構文は、検索条件サブクエリ (Search Condition Subquery) と呼ばれます。これは、主クエリの条件部分で利用され、副問い合わせの結果に基づいて主クエリの行を絞り込みます。
1. 動作の仕組み
この副問い合わせは、主クエリの実行前または行ごとに実行され、結果として得られた値のリストや真偽値が、主クエリの WHERE 句の条件として使用されます。
- 副問い合わせの実行: まず、括弧内の副問い合わせ
(SELECT FIELD1 FROM TABLE2 WHERE FIELD1 >= 1)が実行されます。- この結果、単一の列からなる値のリスト(例:
[1, 5, 8, 10])が返されます。
- この結果、単一の列からなる値のリスト(例:
- 主クエリの評価: 主クエリの
WHERE句、WHERE FIELD IN (...)が評価されます。TABLEのFIELDの値が、副問い合わせから返された値のリストの中に含まれているかどうかがチェックされます。- 条件を満たす行だけが最終的な結果として抽出されます。
2. 利用目的とメリット
WHERE 句のサブクエリは、あるテーブルの値が、別のテーブルの特定の条件を満たす値の集合に含まれるかどうかをチェックするために使用されます。
- 存在チェック: 主テーブルのレコードが、関連する別テーブルのレコードの集合に存在するかどうかを確認します。
- 動的なリスト作成:
IN演算子を使用することで、副問い合わせが返す動的な値のリストに基づいてフィルタリングを行います。これにより、手動でリストを記述する手間が省け、柔軟なクエリが可能です。
3. R言語での対応
R言語の dplyr パッケージでは、この WHERE ... IN (SELECT ...) の操作は、主にフィルタリング (filter()) と 値の集合チェック (%in%) の組み合わせによって実現されます。
| SQLの意図 | R言語 (dplyr) |
WHERE FIELD IN (SELECT F1 FROM T2 ...) | TABLE %>% filter(FIELD %in% (T2 %>% select(F1) ...)) |
コード例
データフレーム customers から、「orders テーブルで $1$ 件以上の注文がある顧客ID」を持つ顧客のみを抽出する例です。
R
# SQL:
# SELECT *
# FROM customers
# WHERE customer_id IN (
# SELECT customer_id FROM orders WHERE order_count >= 1
# );
# R言語:
library(dplyr)
# 1. 副問い合わせ部分: 抽出したい値のユニークなリストを作成
target_ids <- orders %>%
filter(order_count >= 1) %>% # 注文が1件以上
distinct(customer_id) # 顧客IDのリストを抽出
# 2. 主クエリ部分: 主テーブルをリストに基づいてフィルタリング
customers %>%
filter(customer_id %in% target_ids$customer_id)
ポイント:
%in%演算子: Rの%in%は、左側の値が右側のベクトルの要素に含まれているかをチェックする論理演算子です。これはSQLのIN句と完全に一致します。$customer_id:distinct()で作成されたデータフレーム(target_ids)から、実際に値のベクトルを取り出すために$customer_idを使用します。
4. その他の WHERE 句サブクエリの対応
IN 以外にも、SQLのサブクエリに対応するRの操作があります。
| SQL演算子 | R言語での対応 |
WHERE EXISTS (SELECT ...) | semi_join() や inner_join() を使って、結合できる行が存在するかどうかを確認します。 |
WHERE FIELD > (SELECT AVG(FIELD) FROM ...) | filter() を使い、副問い合わせの結果を事前に計算した単一値と比較します。 |
これで、SQLの WHERE 句の副問い合わせを使った条件抽出の操作をR言語で実行できます。