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

我将使用哪种联接来执行查询“从 [用户 A 对游戏投票] 的游戏中选择 *”?

我已经尝试按照Jeff's guide进行操作,但没有得到预期的结果。

4

4 回答 4

6

您将使用连接来建立公共字段INNER之间的关系;gameid

select
  votes.userid,
  games.title
from games
  inner join votes on (votes.gameid = game.gameid)
where
  votes.userid = 'a'
于 2011-08-11T22:37:31.957 回答
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
于 2011-08-11T22:38:18.810 回答
1

您需要的关系运算符是semijoin

大多数 SQL 产品缺少显式的半连接运算符或关键字。标准 SQL-92 有一个MATCH (subquery)谓词,但没有得到广泛实现(真正的关系语言Tutorial D使用关键字 theMATCHING来表示其半连接运算符)。

半连接当然可以使用其他 SQL 谓词来编写。最常见的用法EXISTSor IN (subquery)

根据数据,可能会使用SELECT DISTINCT..INNER JOIN. 但是,在您的情况下,您正在使用SELECT * FROM ...并且INNER JOIN将在投票表上进行投影,从而导致userid与重复列一起被附加到列列表中gameid(如果您选择的 SQL 产品支持它,则使用NATURAL JOIN将解决重复列问题并意味着您也会省略该ON子句)。

INTERSECT如果您的 SQL 产品支持它并且再次取决于数据(特别是当两个表的标题相同时),则使用是另一种可能的方法>

就个人而言,我更喜欢EXISTS在 SQL 中使用半连接,因为连接子句在书面代码中更接近,并且不会导致连接表上的投影,例如

SELECT *
  FROM games
 WHERE EXISTS (
               SELECT * 
                 FROM votes AS v
                WHERE v.gameid = games.gameid
                      AND v.userid = 'a'
              );
于 2011-08-12T07:29:25.907 回答
0

似乎,鉴于您的描述有限,以下将为您提供用户 A 对游戏投票的游戏列表:

select g.gameid, g.title
from games g
inner join votes v
on v.gameid = g.gameid
where v.userid = 'a'
于 2011-08-11T22:45:11.857 回答