在我的期末考试中,我得到了非常讨厌的 SQL、关系代数和关系微积分查询。我得到了这个查询:
查找从“计算机”类别订购所有产品的客户的姓名。(订购了计算机类别中所有产品的客户)
这是架构:
客户(Customer_Id、Cust_First_Name、Cust_Last_Name)
订单 ( 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(在有子句中使用一个子查询):
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 的信息太少,我无法正确理解。
考试结束了,但我仍然对解决方案感兴趣。因为这是 2 小时的考试,其中有 6 个查询、ER 图、ER-To-Relational、标准化到 BCNF、3NF,我想到这个查询怎么会这么难解决。我在这里错过了一些重要的东西吗?
这是一些小样本数据,可以帮助我一点:
提前致谢。