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