您可以使用一個EXISTS
或IN
謂詞查詢。要麼會工作。這個問題實際上首先是關於如何構造一個返回指定結果集的查詢,一旦你有了一個查詢,就可以簡單地將它包裝在一個CREATE VIEW語句中。這裏我會注意到,我們通常不會在MySQL數據庫中使用視圖,這是因爲MySQL優化器的工作方式,它總是將視圖查詢實現爲派生表,這與查看其他視圖查詢的方式不同DBMS)
假設你有單獨的表爲customer
,account
和/或loan
,你可能會需要EXISTS
謂語,謂語IN
,或結合操作,或某種組合那些。
作爲一個例子,這個查詢(下面)使用EXISTS
謂詞來測試在兩個account
表和loan
表匹配行的存在,並從customer
返回行具有至少一個相關聯的帳戶的Perryridge分支,和至少一個相關的貸款。
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的行爲與上述查詢不同,因爲它將返回客戶行的多個副本(如果Perryridge分支有多個帳戶或多個貸款)。我們可以通過包含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)
這應該足以回答您的問題。
UPDATE:
鑑於(比利)
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)
(這似乎WAY更像是一個比它設計和IT專業人士實現的數據庫學術功課或測試問題)
獲得在'Perryr有account
的客戶姓名(depositor
) IDGE」分支:
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
獲取客戶的名稱(borrower
)誰在有loan
'Perryridge' 分支:
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
獲取誰同時擁有一個存款賬戶(depositor
)和貸款客戶的名稱(borrower
)在「Perryridge」分支:
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與相關子查詢謂詞的查詢返回。 (不同的是,連接查詢以上可以引進「重複」,當客戶有在Perryridge多個帳戶或一個以上的貸款。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不是必需的。
視圖基本上是選擇的結果。一旦你找出了選擇應該是什麼,你可以有看法。我不完全理解你的意思是「使用存在或在」 – Xnoise
http://stackoverflow.com/questions/3999600/mysql-difference-between-in-and-exist – Bort
沒有足夠的信息來回答這個問題題。我正在投票結束。 –