我需要什么样的连接?
我有一个投票表:
votes ----------------- userid gameid ------- -------- a 1 a 2 a 3 b 1 b 2
和一个游戏桌:
games ---------------- gameid title ------ ------ 1 foo 2 bar 3 fizz 4 buzz
我将使用什么types的连接来执行查询“从[用户A在游戏中投票]的游戏中select*”?
我试过按照Jeff的指导 ,但是我没有得到预期的结果。
您将使用INNER
连接build立常见的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
您需要的关系运算符是semijoin 。
大多数SQL产品缺less显式的半连接运算符或关键字。 标准SQL-92有一个MATCH (subquery)
谓词,但没有广泛实现(真正的关系语言教程D使用关键字MATCHING
作为其半连接运算符)。
一个semijoin当然可以使用其他的SQL谓词来编写。 最常见的使用EXISTS
或IN (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' );
似乎,鉴于你的有限的描述,以下将会给你一个用户A投票的游戏列表:
select g.gameid, g.title from games g inner join votes v on v.gameid = g.gameid where v.userid = 'a'