はじめに
PostgreSQLにおけるUSING句は、SELECTとDELETEで全く異なる役割を持っています。同じキーワードなのに意味が違うため、混乱しました。
結論:USING句の2つの役割
| 文脈 | 役割 |
|---|---|
| SELECT文(JOIN時) | 結合条件の簡略記法 |
| DELETE文 | 他テーブルを参照するための句 |
SELECT文でのUSING句
概要
JOINで結合するとき、両テーブルに同じ名前のカラムがあれば、ON句の代わりにUSING句で簡潔に書けます。
ON句との比較
-- ON句を使う場合
SELECT *
FROM employees
INNER JOIN departments
ON employees.department_id = departments.department_id;
-- USING句を使う場合(同じ結果)
SELECT *
FROM employees
INNER JOIN departments
USING (department_id);
USING句の特徴
- カラム名が同じ場合のみ使用可能
- 結合カラムが結果に1回だけ表示される(同じものなので統一される)
- 結合カラムはどのテーブルの列かという情報を失う
-- employees.って書き方はできない
SELECT employees.department_id -- USINGで指定したカラムは修飾できない
FROM employees
INNER JOIN departments
USING (department_id);
-- 正しい書き方
SELECT department_id -- テーブル名なしで参照
FROM employees
INNER JOIN departments
USING (department_id);
複数カラムでの結合
カンマ区切りで複数カラムを指定できます。
SELECT *
FROM table1
INNER JOIN table2
USING (id, name);
カラム名が違う場合はUSING句を使えない
実際は、departmentsテーブルの主キーはdepartment_idではなく、シンプルにidと命名されることが多いのであまり使いどころのイメージが湧きません。
SELECT文における、USING句は「たまたまカラム名が揃っている」ときに少しだけ楽ができる程度の機能かな
DELETE文でのUSING句
概要
PostgreSQLのDELETE文では、USING句を使って他のテーブルを参照できます。これは標準SQLにはないPostgreSQLの拡張機能です。
SELECT文のUSINGとは全く別物なので注意してください。
基本構文
DELETE FROM 削除対象テーブル
USING 参照テーブル
WHERE 結合条件;
具体例
-- 日本の顧客の注文をすべて削除する
DELETE FROM orders
USING customers
WHERE orders.customer_id = customers.customer_id
AND customers.country = 'Japan';
ordersテーブルから削除しますが、削除対象の特定にcustomersテーブルの情報を使っています。
複数テーブルの参照
USING句では複数のテーブルを参照することもできます。
DELETE FROM orders
USING customers, regions
WHERE orders.customer_id = customers.customer_id
AND customers.region_id = regions.id
AND regions.name = 'Asia';
標準SQLでの書き方(サブクエリ)
USINGを使わない場合はこう
DELETE FROM orders
WHERE customer_id IN (
SELECT customer_id
FROM customers
WHERE country = 'Japan'
);
まとめ
ややこしいのでUSINGは使いません。と決めました。