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

猜你喜欢

转载自blog.csdn.net/zhangyingli/article/details/84196600