我需要一些帮助将SQL查询转换为关系代数。
这是SQL查询:
SELECT * FROM Customer, Appointment
WHERE Appointment.CustomerCode = Customer.CustomerCode
AND Appointment.ServerCode IN
(
SELECT ServerCode FROM Appointment WHERE CustomerCode = '102'
)
;
由于上例中的IN
子查询,我陷入困境。
任何人都可以向我演示如何在关系代数中表达这个SQL查询吗?
非常感谢。
编辑:这是我在关系代数中提出的解决方案。它是否正确?它是否重现了SQL查询?Scodes←ΠServerCode(σCustomerCode='102'(预约))
Ccodes←ΠCustomerCode(Appointment⋉Scodes)
结果←(客户⋉代码)
答案 0 :(得分:4)
您的SQL代码将导致CustomerCode的列重复,并且使用SELECT [ALL]
可能会导致重复的行。因为结果不是关系,所以不能用关系代数表示。
这些问题很容易在SQL中修复:
SELECT DISTINCT *
FROM Customer NATURAL JOIN Appointment
WHERE Appointment.ServerCode IN
(
SELECT ServerCode FROM Appointment WHERE CustomerCode = '102'
)
;
你没有指定你所在的关系代数.Date和Darwen提出了一个名为A的代数,指定了一种名为D的A语言,并设计了一种名为{{3}的D语言}。
教程D使用运算符JOIN
进行自然连接,使用WHERE
进行限制,使用MATCHING
进行半连接,轻微复杂化是SQL中的比较:
CustomerCode = '102'
由于隐式强制,可能会在SQL中将CustomerCode
值与CHAR
值进行比较。教程D是更严格的 - 类型安全,如果你愿意 - 要求你重载相等运算符,或者更实际地,为CHAR
定义一个选择器运算符,它通常与类型具有相同的名称。
因此,上述(修订版)SQL可以在教程D中编写为:
( Customer JOIN Appointment )
MATCHING ( ( Appointment WHERE CustomerCode = CustomerCode ( '102' ) ) { ServerCode } )
答案 1 :(得分:2)
“我如何用这种标准形式的RA表示我的查询?”
这不是“代数类型”的问题,而是“符号类型”。
使用希腊符号的符号通常使用sigma,附加到sigma字符的下标中的限制条件,然后是限制的主题(受限制条件的关系表达式)。
日期避免使用这种表示法,因为使用这些符号排版和/或创建文本通常比使用西方字母表要困难得多(我的数学老师曾告诉我们数学教科书中包含的错误最多)
σ< cond> (< rel exp>)因此表示与(Date的语法)“< rel exp> WHERE< cond>”完全相同的代数表达式。
类似地,对于希腊符号,投影通常使用字母Pi表示,下标中的保留属性列表附加到Pi,以及作为投影的主题的表达式。
Π< attr list> (< rel exp>)因此表示与(日期的语法)“< rel exp> {< attr list>}”完全相同的代数表达式。
运算符的连接族通常用“希腊”符号表示,使用Unicode BOWTIE字符的(变体),或者用整圆圈包围的小写字母“x”组成的字符(通常用于表示完整笛卡尔积,交叉积,...无论你的代数课程如何命名它。)
有些课程使用希腊字母Rho为重命名提供了“希腊符号”符号。附加在下标中的是重命名列表,形式为a1-> b1,a2-> b2,......之后附加的是经历重命名的关系表达式。同样,Date具有非希腊符号等效语法:< rel exp>重命名a1 AS b1,a2 AS b2,...
重要的是要看到这些差异仅仅是语法符号中的差异,而不是“不同的代数”。
修改
可以想象希腊符号表示法是将关系代数编程到APL引擎中的方法,Date的语法是将关系代数编程为类似cobol或PL / 1的引擎的方法(实际上存在这样一个名为Rel的引擎,以及将关系代数编程为类似OO的引擎的方式,可能看起来像关系.NaturalJoin(otherRelation).Matching(yetOtherRelation.Restrict(condition).project(attributesList))。