在我的期末考试中,我遇到了相当棘手的SQL、关系代数和关系演算查询。其中有一个查询如下所示:
找出所有从类别“计算机”中订购所有产品的客户的姓名。 (即订购了计算机类别中每一种产品的客户)
以下是模式:
Customer (Customer_Id, Cust_First_Name, Cust_Last_Name)
Orders (Order_Id, Customer_Id)
Order_items (Order_Item_id, Order_Id, Product_Id)
Product_info (Product_Id, Product_Name, Category)
粗体表示主键,斜体表示外键。
现在,为了将此查询转换为关系代数,我需要使用连接而不是子查询。为了帮助自己,我首先编写SQL,然后将SQL查询转换为关系代数。
以下是我的尝试:
尝试1(使用子查询):
尝试方法2(在having子句中使用一个子查询):
尝试3(使用FROM子查询):
现在,这个查询可以用关系代数来表示,但是效率很低,因为它会重复值。
我的最后一次尝试(无法编译且使用了where子查询):
找出所有从类别“计算机”中订购所有产品的客户的姓名。 (即订购了计算机类别中每一种产品的客户)
以下是模式:
Customer (Customer_Id, Cust_First_Name, Cust_Last_Name)
Orders (Order_Id, Customer_Id)
Order_items (Order_Item_id, Order_Id, Product_Id)
Product_info (Product_Id, Product_Name, Category)
粗体表示主键,斜体表示外键。
现在,为了将此查询转换为关系代数,我需要使用连接而不是子查询。为了帮助自己,我首先编写SQL,然后将SQL查询转换为关系代数。
以下是我的尝试:
尝试1(使用子查询):
select C.Customer_Id
from Customer C
where
(
select count(*)
from product_info
where category = 'Computer'
)=(select count (distinct pi.Product_id)
from orders S, order_items OI, product_info pi
where S.Customer_Id = C.Customer_Id and S.Order_Id = OI.Order_Id and pi.product_id=OI.product_id and category = 'Computer')
尝试方法2(在having子句中使用一个子查询):
select C.Customer_Id
from Customer C, Product_info pi, Orders S, Order_Items oi
where C.Customer_Id = S.Customer_Id and S.Order_Id = OI.Order_Id and OI.Product_Id = pi.Product_Id and pi.category = 'Computer'
group by C.Customer_Id
having count (distinct pi.Product_Id) =
(
select count (*)
from Product_info
where category = 'Computer'
)
尝试3(使用FROM子查询):
select C.Customer_Id
from Customer C, Product_info pi, Orders S, Order_Items oi,
(
select count (*) num
from Product_info
where category = 'Computer'
) numbr
where C.Customer_Id = S.Customer_Id and S.Order_Id = OI.Order_Id and OI.Product_Id = pi.Product_Id and pi.category = 'Computer'
group by C.Customer_Id, numbr.num
having count (distinct pi.Product_Id) = numbr.num
现在,这个查询可以用关系代数来表示,但是效率很低,因为它会重复值。
我的最后一次尝试(无法编译且使用了where子查询):
select *
from Customer C
where not exists
(select *
from (select Order_Id from orders O where O.Customer_Id = C.Customer_Id) S INNER JOIN order_items OI on S.Order_Id = OI.Order_Id
RIGHT OUTER JOIN (select Product_Id from product_info where category ='Computer') PI on PI.Product_Id = OI.Product_Id
where OI.Product_Id = null)
我在某处看到说,在这种情况下可以使用LATERAL,但是关于LATERAL的信息太少了,我无法正确理解它。
考试已经结束,但我仍对解决方案感兴趣。因为这是一个有6个查询、ER图、ER转关系、BCNF规范化和3NF规范化的2小时考试,我想知道为什么这些查询会如此难以解决。我是否遗漏了什么关键信息?
以下是一小部分数据,帮助我稍微理解一下:
提前感谢。