Sql 我需要什么样的加入?

Sql 我需要什么样的加入?,sql,semi-join,Sql,Semi Join,我有一张投票表: votes ----------------- userid gameid ------- -------- a 1 a 2 a 3 b 1 b 2 还有一张游戏桌: games ---------------- gameid title ------ ------ 1 foo 2 bar 3

我有一张投票表:

 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对游戏进行投票]的游戏中选择*”


我尝试了以下操作,但没有得到预期的结果。

您可以使用
内部连接来建立公共
gameid
字段之间的关系

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

这让您可以通过投票获得游戏:

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

看起来,鉴于您的描述有限,下面将为您提供一个用户a对游戏进行投票的游戏列表:

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

您需要的关系运算符是

大多数SQL产品都缺少显式的半联接运算符或关键字。标准SQL-92有一个
MATCH(subquery)
谓词,但没有广泛实现(真正的关系语言使用关键字
MATCHING
作为其半连接运算符)

当然,可以使用其他SQL谓词编写半连接。最常见的用法
存在于(子查询)

根据数据的不同,可以使用
选择DISTINCT..internal JOIN
。但是,如果您使用的是
SELECT*FROM…
,则
内部联接将投射到投票表上,导致
userid
gameid
的重复列一起附加到列列表中(如果您选择的SQL产品支持它,那么使用
NATURAL JOIN
将解决重复列问题,这意味着您也将省略
ON
子句)

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

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

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

太好了!谢谢。我确实在做我的“on”子句错误,我认为这是我的第一个问题。内部连接是有意义的,因为我不希望任何记录两者都不匹配。考虑到模棱两可的问题,回答得很好。这很有趣。它实现了与内部连接相同的功能,但没有从投票表返回值。是否存在显著的性能差异?