EXISTS
クエリでは、またはIN
述語のいずれかを使用できます。どちらでも動作します。
(「ビュー」は本質的にクエリです。したがって、問題は実際には、最初に、指定された結果セットを返すクエリを作成することです。クエリを作成したら、それを CREATE VIEW ステートメントでラップするだけです。ここでは通常、MySQL データベースでビューを使用しません. これは、MySQL オプティマイザーの動作方法によるもので、常にビュー クエリを派生テーブルに実体化します。これは、ビュー クエリが他の DBMS で処理される方法とは異なります.)
customer
、account
および/またはに対して個別のテーブルがあると仮定すると、述語、述語、結合操作、またはそれらの組み合わせがloan
必要になる可能性があります。EXISTS
IN
例として、このクエリ (以下) はEXISTS
述語を使用して、account
テーブルとテーブルの両方に一致する行が存在するかどうかをテストし、ペリーリッジ支店に少なくとも 1 つの関連付けられたアカウントと、少なくとも 1 つの関連付けられたローンを含むloan
行を返します。customer
SELECT c.name
FROM customer c
WHERE EXISTS ( SELECT 1
FROM account a
WHERE a.customer_id = c.id
AND a.branch = 'Perryridge'
)
AND EXISTS ( SELECT 1
FROM loan l
WHERE l.customer_id = c.id
)
このクエリ (以下) は、同等の結果セットを返しますが、IN
述語を使用して、アカウント テーブルとローン テーブルで一致する行を探します。
SELECT c.name
FROM customer c
WHERE c.id IN ( SELECT a.customer_id
FROM account a
WHERE a.branch = 'Perryridge'
)
AND c.id IN ( SELECT l.customer_id
FROM loan l
)
そして、このクエリ (以下) は、JOIN 操作を利用して、一致する行を探します。ペリーリッジ支店に複数の口座がある場合、または複数のローンがある場合、JOIN の動作は上記のクエリとは異なり、顧客行の複数のコピーが返されます。GROUP BY
句を含めることで、これらの重複を簡単に排除できます。
SELECT c.name
FROM customer c
JOIN account a
ON a.customer_id = c.id
AND a.branch = 'Perryridge'
JOIN loan l
ON l.customer_id = c.id
GROUP BY c.id
スキーマに関する情報がないので、列id
がテーブルの主キーであり、とテーブルcustomer
の両方になどを参照する外部キーがあると仮定しました。account
loan
customer_id
customer(id)
これらの各クエリは、異なるパフォーマンス特性を示します。すべてのクエリがインデックスの恩恵を受ける可能性があります
... ON account (customer_id, branch)
... ON loan (customer_id)
... ON customer (id, name)
これはあなたの質問に答えるのに十分なはずです。
アップデート:
与えられた (by ビリー)
branch(branch_name, branch_city, assets)
customer(customer_name, customer_street, customer_city)
account(account_number, branch_name, balance)
loan(loan_number, branch_name, amount)
depositor(customer_name, account_number)
borrower(customer_name, loan_number)
(これは、IT 専門家によって設計および実装されたデータベースよりも、大学の宿題やテストの問題のように思えます。)
'Perryridge' 支店depositor
を持つ顧客 ( ) の名前を取得します。account
SELECT d.customer_name
FROM depositor d
JOIN account a
ON a.account_number = d.account_number
WHERE a.branch_name = 'Perryridge'
GROUP BY d.customer_name
'Perryridge' 支店borrower
を持つ顧客 ( ) の名前を取得します。loan
SELECT b.customer_name
FROM borrower b
JOIN loan l
ON l.loan_number = b.loan_number
AND l.branch_name = 'Perryridge'
GROUP BY b.customer_name
(テーブルから追加の列が必要な場合は、customer
そのテーブルに JOIN を追加します。
SELECT c.customer_name
, c.customer_street
, c.customer_city
FROM customer c
JOIN borrower b
ON b.customer_name = c.customer_name
JOIN loan l
ON l.loan_number = b.loan_number
AND l.branch_name = 'Perryridge'
GROUP
BY c.customer_name
, c.customer_street
, c.customer_city
'Perryridge' 支店で預金口座 ( depositor
) とローン ( ) の両方を持っている顧客の名前を取得します。borrower
SELECT c.customer_name
, c.customer_street
, c.customer_city
FROM customer c
JOIN borrower b
ON b.customer_name = c.customer_name
JOIN loan l
ON l.loan_number = b.loan_number
AND l.branch_name = 'Perryridge'
JOIN depositor d
ON d.customer_name = c.customer_name
JOIN account a
ON a.account_number = d.account_number
AND a.branch_name = 'Perryridge'
GROUP
BY c.customer_name
, c.customer_street
, c.customer_city
ORDER
BY c.customer_name
, c.customer_street
, c.customer_city
EXISTS 述部と相関サブクエリを使用するクエリでは、ほぼ同じ結果セットを返すことができます。(違いは、顧客がペリーリッジで複数の口座または複数のローンを持っている場合、上記の JOIN クエリが「重複」を導入する可能性があることです。そこの GROUP BY 句は重複を排除します。)
SELECT c.customer_name
, c.customer_street
, c.customer_city
FROM customer c
WHERE EXISTS
( SELECT 1
FROM borrower b
WHERE b.customer_name = c.customer_name
AND EXISTS
( SELECT 1
FROM loan l
WHERE l.loan_number = b.loan_number
AND l.branch_name = 'Perryridge'
)
)
AND EXISTS
( SELECT 1
FROM depositor d
WHERE d.customer_name = c.customer_name
AND EXISTS
( SELECT 1
FROM account a
WHERE a.account_number = d.account_number
AND a.branch_name = 'Perryridge'
)
)
ORDER
BY c.customer_name
, c.customer_street
, c.customer_city
customer
このクエリは、テーブルから行を返すだけなので、重複は発生しません。(このクエリが重複を返す唯一の方法は、テーブルに重複行があるcustomer
場合です。) テーブルに重複行がない場合customer
、GROUP BY は必要ありません。