现在的位置: 首页 > 综合 > 正文

【Database】数据库 — 用SQL语句实现关系代数的除法操作

2013年05月04日 ⁄ 综合 ⁄ 共 1593字 ⁄ 字号 评论关闭

SQL语句表示除法操作

首先,定义我们要使用的三张表。

1.CREATE TABLE depositor(
	customer_name  CHAR(20),
	account_number  CHAR(10),
	PRIMARY KEY(customer_name, account_number)
)
2.CREATE TABLE account(
	account_number CHAR(10),
	branch_name  CHAR(15),
	balance  NUMERIC(12,2)
	PRIMARY KEY(account_number)
)
3.CREATE TABLE branch(
	branch_name  CHAR(15),
	branch_city 	 CHAR(30),
	assets		 NUMERIC(16,2)
	PRIMARY KEY(branch_name)
)

有了这三张表之后,来看我们的问题。

“Find all customers who have an account count at all the branches located in Brooklyn”

翻译过来的意思就是找到在Brooklyn的所有支行,都有账户的客户。

 

我们先把答案写在这里:

SELECT  DISTINCT S.customer_name
FROM  depositor as S
WHERE NOT EXISTS ((SELECT branch_name
		FROM branch
		WHERE branch_city = ‘Brooklyn’)
	       EXCEPT
		(SELECT R.branch_name
		 FROM depositor as T, account as R
   		 WHERE T.account_number = R.account_number 
		 AND   S.customer_name = T.customer_name))

 

这就是用SQL语句实现的一个简单除法操作。

我们把问题一个一个分开来解释:

1.      
  
我们能看到这个查询在主查询中用到了depositor表。而在它的嵌套子查询中,同样用到了这张表。所以,这个查询为相关子查询

相反,如果这个嵌套查询在子查询中没有用到主查询中的表,那么我们称之为无关子查询。

相关子查询和无关子查询的在使用上的区别是什么呢?如果一个嵌套查询中包含无关子查询。那么我们会先执行子查询,在子查询结果的这张表中,我们再执行主查询。也就是说在子查询结果的基础之上再进行查询。

而相关子查询不同,在主查询中扫描一条记录,比如果我们拿到了一条depositor的记录A,我们会把A带入到子查询中,看结果是否为真,如果为真,那么就输出A。然后取depositor的表中的下一项B。一次逐条扫描。

2.      
  
在数据库中,如果我们想表示关系A包含关系B。我们应该怎么表示呢?

对!用NOT EXISTS关键字。

如果我们说A包含B,那么也就等价于NOT EXISTS ( B EXCEPT A)

换句话说就是 ==》不存在属于B而不属于A的元组。那么也就是A包含B

 

         现在再看我们的答案。显然清晰多了。

操作B

SELECT branch_name
	FROM branch
	WHERE branch_city = ‘Brooklyn’

执行的结果是:找到地点在Brooklyn的所有支行。

操作A:

SELECT R.branch_name
FROM depositor as T, account as R
WHERE T.account_number = R.account_number 
AND   S.customer_name = T.customer_name 

 

执行的结果是:客户S.1有账户的所有支行。

 现在如果A的结果包含B的结果,也就是说一个客户它所有有账户的支行包括了地点在Brooklyn的所有支行,那么我们就把客户S.1输出出来,再去扫描S.2。同理,结果为真就进行输出,结果为假就去扫描下一条记录,直到这个表的结束。这样我们就得到了我们想要的结果。

 

 

抱歉!评论已关闭.