1. 程式人生 > >第3章 SQL 習題 - 3.15

第3章 SQL 習題 - 3.15

3.15 考慮圖3-19中的銀行資料庫,其中加下劃線的是主碼。為這個關係資料庫構造出如下SQL查詢:

a.找出在"Brooklyn"的所有支行都有賬戶的所有客戶。

這個銀行資料庫咱們在習題3.8中已經建立了。當時咱們建立的所有支行資料所在地都是北京。這樣題目中提到的所在地咱們使用北京。

這樣我們先找出在北京的某個支行有賬戶的所有客戶:

select customer_name, branch_name from depositor
natural join account natural join branch
where branch_city = '北京';

結果如下:

 customer_name | branch_name 
---------------+-------------
 客戶_1        | 銀行支行_1
 客戶_1        | 銀行支行_2
 客戶_2        | 銀行支行_3
 客戶_3        | 銀行支行_3
 客戶_4        | 銀行支行_4
 客戶_5        | 銀行支行_1
 客戶_6        | 銀行支行_1
 客戶_7        | 銀行支行_4
 客戶_8        | 銀行支行_4
(9 rows)

從上面結果看,沒有任何客戶擁有北京的所有支行的賬戶,這樣為了後面能有查詢結果,我們給客戶_1在銀行支行_3, 4分別再建立兩個賬戶吧:

insert into account values ('賬戶_10', '銀行支行_3');
insert into account values ('賬戶_11', '銀行支行_4');
insert into depositor values ('客戶_1', '賬戶_10');
insert into depositor values ('客戶_1', '賬戶_11');

再次查詢最開始的SQL,結果如下:

 customer_name | branch_name 
---------------+-------------
 客戶_1        | 銀行支行_1
 客戶_1        | 銀行支行_2
 客戶_2        | 銀行支行_3
 客戶_3        | 銀行支行_3
 客戶_4        | 銀行支行_4
 客戶_5        | 銀行支行_1
 客戶_6        | 銀行支行_1
 客戶_7        | 銀行支行_4
 客戶_8        | 銀行支行_4
 客戶_1        | 銀行支行_3
 客戶_1        | 銀行支行_4
(11 rows)

這樣客戶_1就擁有的所有支行的賬戶,接下來我們以這些關係建立一個臨時關係customer_branch:

with customer_branch(customer_name, branch_name) as (
	select customer_name, branch_name from depositor
	natural join account natural join branch
	where branch_city = '北京'
)

然後我們再建立一個臨時關係branch_name_beijing,這個關係儲存著北京的所有支行名稱:

with branch_name_beijing(branch_name) as (
	select branch_name from branch where branch_city = '北京'
)

如果一個客戶在北京的所有支行中都有賬戶,也就是說cutomer_branch關係中的某個customer_name的對應的branch_name組成的集合應該是關係branch_name_beijing的列branch_name組成的集合的子集,也就是說後一個集合減去前一個集合,值應該為空,那麼查詢應該如下:

with customer_branch(customer_name, branch_name) as (
	select customer_name, branch_name from depositor
	natural join account natural join branch
	where branch_city = '北京'
), branch_name_beijing(branch_name) as (
	select branch_name from branch where branch_city = '北京'
)
select distinct customer_name
from customer_branch as S
where not exists (
	(select branch_name from branch_name_beijing)
	except
	(select branch_name from customer_branch where customer_name = S.customer_name)
	);
 customer_name 
---------------
 客戶_1
(1 row)

b.找出銀行的所有貸款額的總和。

select branch_name, sum(amount) from loan group by branch_name;
 branch_name |   sum    
-------------+----------
 銀行支行_3  |   410.00
 銀行支行_4  | 12484.00
 銀行支行_2  |    45.00
 銀行支行_1  |   583.00
(4 rows)

c.找出總資產至少比位於Brooklyn的某一家支行要多的所有支行名字。

select * from branch;
 branch_name | branch_city |  assets  
-------------+-------------+----------
 銀行支行_1  | 北京        | 66666.00
 銀行支行_2  | 北京        | 77777.00
 銀行支行_3  | 北京        | 88888.00
 銀行支行_4  | 北京        | 99999.00
(4 rows)

從結果看,銀行支行_1的資產最少,那麼查詢結果也應該是其他3個支行,我們執行我們所寫的SQL語句吧:

select branch_name from branch 
where assets > some(
	select assets from branch where branch_city = '北京'
);
 branch_name 
-------------
 銀行支行_2
 銀行支行_3
 銀行支行_4
(3 rows)