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)
4

1 に答える 1

1

EXISTSクエリでは、またはIN述語のいずれかを使用できます。どちらでも動作します。

(「ビュー」は本質的にクエリです。したがって、問題は実際には、最初に、指定された結果セットを返すクエリを作成することです。クエリを作成したら、それを CREATE VIEW ステートメントでラップするだけです。ここでは通常、MySQL データベースでビューを使用しません. これは、MySQL オプティマイザーの動作方法によるもので、常にビュー クエリを派生テーブルに実体化します。これは、ビュー クエリが他の DBMS で処理される方法とは異なります.)

customeraccountおよび/またはに対して個別のテーブルがあると仮定すると、述語、述語、結合操作、またはそれらの組み合わせがloan必要になる可能性があります。EXISTSIN

例として、このクエリ (以下) は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の両方になどを参照する外部キーがあると仮定しました。accountloancustomer_idcustomer(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 は必要ありません。

于 2012-12-27T20:35:59.127 に答える