2012-12-27 53 views
0

創建一個視圖,該視圖包含在Perryridge分支中擁有貸款和帳戶的所有客戶的名稱。創建視圖(存在或位於)

對此的任何想法?我很困惑是否要使用存在或


的表是:

customer (customer_name, customer_street, customer_city) 
    depositor (customer_name, account_number) 
    account (account_number, branch_name, balance) 
    borrower (customer_name, loan_number) 
    loan (loan_number, branch_name, amount) 
+1

視圖基本上是選擇的結果。一旦你找出了選擇應該是什麼,你可以有看法。我不完全理解你的意思是「使用存在或在」 – Xnoise

+0

http://stackoverflow.com/questions/3999600/mysql-difference-between-in-and-exist – Bort

+1

沒有足夠的信息來回答這個問題題。我正在投票結束。 –

回答

1

您可以使用一個EXISTSIN謂詞查詢。要麼會工作。這個問題實際上首先是關於如何構造一個返回指定結果集的查詢,一旦你有了一個查詢,就可以簡單地將它包裝在一個CREATE VIEW語句中。這裏我會注意到,我們通常不會在MySQL數據庫中使用視圖,這是因爲MySQL優化器的工作方式,它總是將視圖查詢實現爲派生表,這與查看其他視圖查詢的方式不同DBMS)

假設你有單獨的表爲customeraccount和/或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 

缺席有關您的架構的任何信息,我在這裏做了一些假設列idcustomer表的主鍵,並且每個accountloan表都有一個外鍵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不是必需的。

+0

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) – Billy

+0

@Billy,this信息可能會更好地包含在您的問題中,而不是作爲對我的答案的評論。 – spencer7593