2011-08-11 80 views
2

我有一個投票表:我需要什麼樣的連接?

votes 
----------------- 
userid gameid 
------- -------- 
    a  1 
    a  2 
    a  3 
    b  1 
    b  2 

和遊戲桌:

games 
---------------- 
gameid title 
------ ------ 
    1  foo 
    2  bar 
    3  fizz 
    4  buzz 

我會用什麼樣的聯接執行查詢「SELECT * FROM遊戲中[用戶A投票遊戲]」?我試過Jeff's guide,但我沒有得到預期的結果。

回答

6

您將使用INNER連接建立常見的gameid字段之間的關係;

select 
    votes.userid, 
    games.title 
from games 
    inner join votes on (votes.gameid = game.gameid) 
where 
    votes.userid = 'a' 
+0

完美!謝謝。我確實在做錯我的「上」條款,我認爲這是我的第一個問題。 Inner Join是有意義的,因爲我不希望任何兩個記錄都不匹配。 – xdumaine

1

這讓你帶票遊戲:

SELECT 
    g.title 
    v.userid 
FROM 
    games g 

    INNER JOIN votes v 
    ON g.gameid = v.gameid 

這可以讓你所有的遊戲,即使不進行表決:

SELECT 
    g.title 
    v.userid 
FROM 
    games g 

    LEFT JOIN votes v 
    ON g.gameid = v.gameid 
+0

好的答案,給出了一個模棱兩可的問題。 – Karl

0

好像,給你限制說明,以下內容會爲您提供用戶A在遊戲中投票的遊戲列表:

select g.gameid, g.title 
from games g 
inner join votes v 
on v.gameid = g.gameid 
where v.userid = 'a' 
1

您需要的關係運算符是semijoin

大多數SQL產品缺少顯式的半連接運算符或關鍵字。標準SQL-92有一個MATCH (subquery)謂詞,但沒有廣泛實現(真正的關係語言Tutorial D使用關鍵字MATCHING作爲其半連接運算符)。

當然可以使用其他SQL謂詞編寫一個semijoin。最常見的用途是EXISTSIN (subquery)

根據數據有可能使用SELECT DISTINCT..INNER JOIN。但是,在您的情況下,您使用的是SELECT * FROM ...,而INNER JOIN將投影到投票表上,從而導致userid被附加到列表列表以及gameid的重複列(如果您選擇的SQL產品支持該列,則使用NATURAL JOIN將解決重複列問題,並意味着你會忽略ON條款)。

使用INTERSECT是另一種可行的方法,如果你的SQL產品支持,並再次根據數據(特別是,當兩個表的標題是相同的)>

就個人而言,我更喜歡在SQL中使用EXISTS用於半連接,因爲連接子句在書寫代碼中更接近,並且不會導致對連接表的投影,例如

SELECT * 
    FROM games 
WHERE EXISTS (
       SELECT * 
       FROM votes AS v 
       WHERE v.gameid = games.gameid 
         AND v.userid = 'a' 
      ); 
+0

這很有趣。它實現與Inner Join相同的功能,但不返回票表中的值。是否有任何顯着的性能差異? – xdumaine