如何在不使用if-else的情况下编写relax-join表达式?

时间:2012-02-20 00:12:48

标签: sql join relational-algebra

relax-join运算符定义为:

  

如果关系R和S的自然连接是非空的,则返回   这次加入的结果;否则,返回R的笛卡尔积   和S.

问题是编写一个关系代数和SQL,它返回两个关系的relax-join,但不使用IF-THEN-ELSE。

3 个答案:

答案 0 :(得分:1)

由于这被标记为家庭作业,我想我只应该提供指导。

以下是需要考虑的事项:

  1. 联盟将允许您合并两个查询的结果A& B. A,B或两者是否包含记录无关紧要。

  2. 交叉连接和自然连接将生成相同的结果列。 更新 @ {1}}中的情况并非如此,正如@ypercube指出的那样。您可以编写您的sql,以便它们返回相同的列,因此可以在union中使用它们。这可能适用于您,也可能不适合您。

  3. 根据您的方案,如果您要返回记录,则交叉连接将始终生成记录。自然联接可能会也可能不会。

  4. 我希望这不是太多的暗示,很难判断我是在透露太多还是不够。当你搞清楚时,请告诉我们!

    <强>更新

    我不知道经过x段时间我们应该发布实际答案,但这是我暗示的伪问题:

    MYSQL

答案 1 :(得分:1)

因为这是一个涉及关系的运算符,所以可以假设结果也必须是SQL中可能存在的关系,即不重复的列,没有重复的行,没有空值等。另外,请注意,如果没有关系属性RS是常见的,那么它们的自然连接将产生与其产品相同的结果。

正如已经指出的,如果RS具有一些共同的属性(相同的名称,相同的类型),那么在SQL中,表的乘积将产生重复的列。忽略查询INFORMATION_SCHEMA的想法,不能在SQL中推广relax-join。相反,我们必须使用显式投影,即具有显式属性的SELECT子句,其中至少有一些必须是“点限定”。比方说我们R { x, y }S { y, z } y是公共列,然后产品可以表示为:

SELECT DISTINCT R.x, R.y, S.z 
  FROM R CROSS JOIN S

也就是说,R的所有属性和S的属性的投影都不常见。还有许多其他可能性会产生相同的结果,但都涉及所涉及属性的先验知识,包括是否有任何共同点。

在接受投影必须明确的情况下,通过将自然连接表达为其theta连接等效,即[INNER] JOINON子句,不会丢失任何内容:

SELECT DISTINCT R.x, R.y, S.z 
  FROM R JOIN S ON R.y = S.y

同样,我们不需要SQL关键字CORRESPONDING(如UNION CORRESPONDING中所述)。令人高兴的是,这一切都意味着我的查询将全部运行在我选择的SQL产品上(SQL Server)!

我认为J Cooper暗示的一种方法是a)自然连接(可能是空集)和b)自然连接为空集的产品的结合:

SELECT R.*, S.z 
  FROM R JOIN S ON R.y = S.y
UNION 
SELECT R.*, S.z 
  FROM R CROSS JOIN S 
 WHERE NOT EXISTS ( SELECT *
                      FROM R JOIN S ON R.y = S.y );

另一种方法是产品减去对称差异('互斥元组'),其中自然连接不是空集:

SELECT R.*, S.z 
  FROM R CROSS JOIN S 
EXCEPT
SELECT R.*, S.z 
  FROM R JOIN S ON R.y <> S.y
 WHERE EXISTS ( SELECT * 
                  FROM R JOIN S ON R.y = S.y );

答案 2 :(得分:0)

SQL:

R1 = A equi_join B
R2 = A X B

R1
U
R2 not exists R1

这就是答案。

由于作业截止日期已结束:

R1 = A equi_join B
R2 = A X B

R3 = R2.* (R1 X R2)
R4 = R2 - R3

return (R1 U R4)