關係代數——基本運算(2)

上一節講了關係代數的一些基本運算,本節繼續講解其餘的基本運算:笛卡爾積和更名運算。

笛卡爾積x

笛卡爾積運算使得我們可以將任意兩個關係的信息組合在一起。

形式的說,R × S 被定義爲:

R \times S = {r \cup sr \in Rs \in S}

假設我們希望找出所有在Perryridge支行有貸款的客戶姓名。

爲了實現這一要求,我們同時需要關係loan和關係borrower中的信息。

σbranch_name="Perryridge"(borrower \times loan)

然而,customer_name列卻可能包含在Perryridge支行沒有貸款的客戶。

因爲笛卡爾積中保留了所有可能的由一個來自borrower的元組和一個來自loan的元組構成的元組對。

由於笛卡爾積運算將loan中的每個元組同borrower中的每個元組進行聯繫,而我們又知道如果客戶在Perryridge支行有貸款,則borrower \times loan中必定存在某個元組,其中包含了該客戶的姓名,並且borrwoer.loan_number=loan.loan_number

因此如果我們用下面的表達式就可以得到borrower \times loan中與在Perryridge支行有貸款的客戶相關的所有元組。

σborrwoer.loan_number=loan.loan_number

(σbranch_name="Perryridge"(borrower \times loan) )

最後,由於我們只需要customer_name,我們進行投影:

πcustomer_name(σborrower.loan_number=loan.loan_number

(σbranch_name="Perryridge"(borrower \times loan) ) )

這就是我們要查詢的結果。

其相應的查詢語句爲:

  1. mysql> select customer_name from borrower, loan 
  2.     -> where borrower.loan_number=loan.loan_number 
  3.     -> and branch_name="Perryridge"
  4. +---------------+ 
  5. | customer_name | 
  6. +---------------+ 
  7. | Hayes         | 
  8. | Admas         | 
  9. +---------------+ 
  10. 2 rows in set (0.00 sec) 

更名運算 (ρ)

更名運算的表達式是:ρ(E)

假設關係代數表達式En元的,則表達式

ρx(A1,A2……An(E)

返回表達式E的結果,並賦給它名字x,同時將各屬性更名爲A1,A2……An

1查詢“找出銀行中最大的賬戶餘額”。

我們的策略是:

(1)    首先計算出一個由非最大的餘額構成的臨時關係;

(2)    計算關係πbalance (account)和剛纔算出的臨時關係之間的集合差。

步驟一:爲了計算該臨時關係,我們需要比較所有賬戶餘額的值。要做這樣的比較,我們可以通過笛卡爾積account ×account並構造一個選擇來比較任意兩個出現在同一元組中的餘額。

πaccount.balance (σacount.balance<d.balance (account×ρd (account) ) )

其相應的查詢語句爲:

步驟二:查找銀行中最大餘額的查詢:

πbalance(account) -

πaccount.balance(σacount.balance<d.balance (account×ρd (account)))

 

其相應的查詢語句爲:

  1. mysql> select balance from account 
  2.     ->  where balance not in 
  3.     -> (select distinct account.balance from account, account d 
  4.     -> where account.balance<d.balance); 
  5. +---------+ 
  6. | balance | 
  7. +---------+ 
  8. |     900 | 
  9. +---------+ 
  10. 1 row in set (0.00 sec) 

2:查詢“找出所有與Smith居住在同一城市同一街道的客戶”

首先得到Smith居住的城市和街道:

πcustomer_street, customer_city(σcustomer_name= "Smith " (customer) )

其相應的查詢語句爲:

  1. mysql> select customer_street, customer_city 
  2.     -> from customer 
  3.     -> where customer_name="Smith"
  4. +-----------------+---------------+ 
  5. | customer_street | customer_city | 
  6. +-----------------+---------------+ 
  7. | North           | Rye           | 
  8. +-----------------+---------------+ 
  9. 1 row in set (0.00 sec) 

爲了找出居住在這個城市這條街道的其它客戶,我們必須再次引用customer關係。現在對上面的表達式進行更名運算,給此表達式的結果以名字smith_addr,並將其屬性更名爲streetcity,替換原有的customer_streetcustomer_city:

πcustomer.customer_name

(σcustomer.customer_street=smith_addr.streetcustomer_city=smith_addr.city

(customer×ρsmith_addr(street,city)

πcustomer_street, customer_city(σcustomer_name= "Smith " (customer)))))

其相應的查詢語句爲:

  1. mysql> select customer.customer_name from customer, 
  2.     -> (select customer_street street, customer_city city 
  3.     ->   from customer 
  4.     ->   where customer_name="Smith") smith_addr 
  5.     -> where customer.customer_street=smith_addr.street and 
  6.     -> customer_city=smith_addr.city; 
  7. +---------------+ 
  8. | customer_name | 
  9. +---------------+ 
  10. | Curry         | 
  11. | Smith         | 
  12. +---------------+ 
  13. 2 rows in set (0.00 sec) 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章