2012-02-20 59 views
1

的放鬆聯接運算符被定義爲:如何在不使用if-else的情況下編寫relax-join表達式?

如果自然連接關係的R和S非空,則返回 的這個連接的結果;否則,返回[R 和S.

的問題是寫一個關係代數和SQL返回兩個關係的放鬆聯接的笛卡爾乘積,而不是使用IF-THEN-ELSE。

+0

哪個RDBMS?哪個版本? – 2012-02-20 00:43:46

+0

這甚至可能在SQL?這兩個選項將有不同數量的列。 – 2012-02-20 01:09:34

+0

@ypercube - 這是,看看我的提示。爲什麼自然連接與交叉連接會產生不同的列數? – 2012-02-20 01:11:49

回答

1

由於這被標記爲家庭作業,我想我只是應該提供指導。

這裏有一些事情要考慮:

  1. 一名工會將允許你結果組合兩個查詢一個& B.如果A,B或兩者包含的記錄與否沒關係的。

  2. 交叉連接和自然連接將產生相同的結果列。 UPDATE這是不正確的MYSQL @ypercube指出。你可以編寫你的sql,以便它們返回相同的列,因此可以在一個union中使用它們。這可能會或可能不適合你。

  3. 鑑於您的情況,如果您打算返回記錄,交叉連接將始終生成記錄。自然連接可能會也可能不會。

我希望這不是太多的暗示,很難判斷我是否透露太多或不夠。讓我們知道你何時弄明白!

UPDATE

我不知道,之後的時間X量我們應該張貼實際的答案,但這裏是僞查詢我是在暗示:

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

UNION 

SELECT * 
FROM R 
NATURAL JOIN S 
+0

謝謝庫珀。我知道了。由於AxB總是給出一個結果,它可能等於或不等於A join B的結果。只需通過union(AxB - A join B)和A join B,就可以解決這兩種情況下的問題。 – user1219940 2012-02-20 05:46:14

+0

@ user1219940 - 不完全,'AxB - 一個連接B',尤其是減號'-'不會給你想要的結果。在'A join B'確實產生記錄的情況下,你將以兩個查詢的記錄結束。基本上,如果你要從'AxB'返回記錄,就必須滿足一個條件...... – 2012-02-20 13:06:26

+0

我必須說,在處理數千個數據庫的30年中,我從未需要這樣做。通常使用自然連接是一個可怕的想法時期(並且有幾個數據庫不允許)。所以不要花費太多精力來學習這一點。 – HLGEM 2012-02-20 21:36:30

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) 
+0

我對這個答案做了一些編輯,請仔細檢查它們。 – 2012-02-22 12:09:58

1

因爲這是涉及到關係的運營商,它可以假設的結果也必須是隻要有可能在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連接等同即[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庫珀暗示,是一種)自然連接(可能是空集的聯合),和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);