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'
);