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

发布于 2025-01-06 23:14:02 字数 169 浏览 1 评论 0原文

松弛连接运算符定义为:

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

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

The relax-join operator is defined as:

if the natural join of the relations R and S is nonempty, then return
the result of this join; otherwise, return the Cartesian product of R
and S.

The problem is to write a relational algebra and SQL that return the relax-join of two relations, but not use IF-THEN-ELSE.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

成熟的代价 2025-01-13 23:14:02

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

以下是需要考虑的一些事项:

  1. 并集将允许您组合两个查询 A 和 A 的结果; B. A、B 或两者是否包含记录并不重要。

  2. 交叉连接和自然连接将产生相同的结果列。 更新 正如 @ypercube 所指出的,MYSQL 中的情况并非如此。您可以编写 sql,以便它们返回相同的列,因此可以在联合中使用两者。这可能适合您,也可能不适合您。

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

我希望这不是太多的暗示,很难判断我是否透露太多或还不够。当您弄清楚时请告诉我们!

更新

我不知道在 x 时间后我们应该发布实际答案,但这是我暗示的伪查询:

SELECT * 
FROM R
CROSS JOIN S
WHERE NOT EXISTS (
    SELECT *
    FROM R
    NATURAL JOIN S
)

UNION

SELECT *
FROM R
NATURAL JOIN S

Since this is tagged as homework I guess i am only supposed to provide guidance.

Here are some things to consider:

  1. A union will allow you to combine results of two queries A & B. It doesn't matter if A, B or both contain records or not.

  2. A cross join and a natural join will produce the same result columns. UPDATE This is not true in MYSQL as @ypercube has pointed out. You could write your sql so they do return the same columns and therefore could use both in a union. This may or may not work for you.

  3. Given your scenario, if you are ever going to return records, the cross join will always produce records. The natural join may or may not.

I hope that isn't too much of a hint, it's hard to judge if I'm revealing too much or not enough. let us know when you figure it out!

UPDATE

I wasn't aware that after x amount of time we were supposed to post the actual answer, but here is the psuedo query I was hinting at:

SELECT * 
FROM R
CROSS JOIN S
WHERE NOT EXISTS (
    SELECT *
    FROM R
    NATURAL JOIN S
)

UNION

SELECT *
FROM R
NATURAL JOIN S
萝莉病 2025-01-13 23:14:02

因为这是一个涉及关系的运算符,所以可以假设结果也必须是 SQL 中可能的关系,即没有重复的列、没有重复的行、没有空值等。顺便说一句,请注意,如果没有关系 RS 很常见,那么它们的自然连接将产生与其乘积相同的结果。

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

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

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

接受投影必须是显式的之后,通过将自然连接表示为其等价的 theta 连接,即带有 ON 子句的 [INNER] JOIN ,不会有任何损失:

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 );

Because this is an operator involving relations, it can be assumed that the result must also be a relation insofar as is possible in SQL i.e. not duplicate columns, no duplicate rows, no nulls, etc. As an aside, note that if no attributes of relations R and S are common then their natural join will yield the same result as their product.

As already pointed out, if R and S have some common attributes (same name, same type) then in SQL the product of the tables will produce duplicate columns. Disregarding the idea of querying the INFORMATION_SCHEMA, the relax-join cannot be generalized in SQL. Instead, we must use explicit projections i.e. SELECT clauses with explicit attributes, at least some of which must be 'dot qualified'. Say for example we have R { x, y } and S { y, z } with y being a common column then the product can be expressed as:

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

That is, the projection of all attributes of R and the attributes of S known not to be common. There are numerous other possibilities that will yield the same result but all involve prior knowledge of the attributes involved including whether any are common.

Having accepted that the projection must be explicit, nothing is lost by expressing the natural join as its theta join equivalent i.e. [INNER] JOIN with an ON clause:

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

Likewise, we have no need for the SQL keyword CORRESPONDING (as in UNION CORRESPONDING). Happily, this all means that my queries will all run on my SQL product of choice (SQL Server)!

One approach, I think hinted at by J Cooper, is the union of a) the natural join (which could be the empty set), and b) the product where the natural join is the empty set:

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 );

Another approach is the product minus the symmetric difference ('mutually exclusive tuples') where the natural join is not the empty set:

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 );
娇纵 2025-01-13 23:14:02

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)

SQL:

R1 = A equi_join B
R2 = A X B

R1
U
R2 not exists R1

This is answer for this.

Since the homework due date is over:

R1 = A equi_join B
R2 = A X B

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

return (R1 U R4)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文