What kind of join do I need?

可紊 提交于 2019-11-26 09:05:00

问题


I have a votes table:

 votes
-----------------
 userid   gameid
-------  --------
   a        1
   a        2
   a        3
   b        1
   b        2

and a games table:

 games
----------------
 gameid   title
 ------   ------
    1       foo
    2       bar
    3       fizz
    4       buzz

What kind of a join would I use to perform the query \"Select * from games where [user A voted on the game]\"?

I\'ve tried following Jeff\'s guide, but I\'m not getting the expected results.


回答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'



回答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



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



回答4:


Seems like, given your limited description, the following would get you a list of games where user A voted on the game:

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


来源:https://stackoverflow.com/questions/7033748/what-kind-of-join-do-i-need

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!