What kind of join do I need?
Solution 1:
You would use an INNER
join to establish the relationship between the common gameid
field;
select
votes.userid,
games.title
from games
inner join votes on (votes.gameid = game.gameid)
where
votes.userid = 'a'
Solution 2:
This gets you the games with a vote:
SELECT
g.title
v.userid
FROM
games g
INNER JOIN votes v
ON g.gameid = v.gameid
This gets you all of the games, even if not voted on:
SELECT
g.title
v.userid
FROM
games g
LEFT JOIN votes v
ON g.gameid = v.gameid
Solution 3:
The relational operator you require is semijoin.
Most SQL products lacks an explicit semijoin operator or keyword. Standard SQL-92 has a MATCH (subquery)
predicate but is not widely implemented (the truly relational language Tutorial D uses the keyword the MATCHING
for its semijoin operator).
A semijoin can of course be written using other SQL predicates. The most commonly seen use EXISTS
or IN (subquery)
.
Depending on the data it may be possible to use SELECT DISTINCT..INNER JOIN
. However, in your case you are using SELECT * FROM ...
and an INNER JOIN
will project over the votes table resulting in userid
being appended to the column list along with a duplicate column for gameid
(if your SQL product of choice supports it, using NATURAL JOIN
would solve the duplicate column problem and mean you would omit the ON
clause too).
Using INTERSECT
is another possible approach if your SQL product supports it and again depending on the data (specifically, when the headings of the two tables are the same)>
Personally, I prefer to use EXISTS
in SQL for semijoin because the join clauses are closer together in the written code and doesn't result in projection over the joined table e.g.
SELECT *
FROM games
WHERE EXISTS (
SELECT *
FROM votes AS v
WHERE v.gameid = games.gameid
AND v.userid = 'a'
);