查询一对多对表关系的最有效方法

时间:2011-11-05 16:22:53

标签: mysql sql select join

我有3个描述游戏的MySQL表:

  1. gamelist {gameId,... with Primary(gameId)} =存储有关每个游戏会话的信息。
  2. userlist {userId,... with Primary(userId)} =存储每个用户的信息。
  3. game2user {gameId,userId ... with Primary(gameId,userId)} =存储每个游戏会话中涉及的用户(一个游戏会话指向两个或更多用户)。
  4. 现在,对于某个userId,我需要检索包含该游戏会话中涉及的所有用户名称的游戏列表。

    我到目前为止最好的是:

    SELECT gl.gameid, gl.type, [...], ul.userid, ul.username
    FROM userlist as ul, gamelist as gl, game2users as g2u
    WHERE g2u.userid = a_certain_numeric_id AND
          ul.userid = g2u.userid AND
          gl.gameid = g2u.gameid`
    

    这将从游戏列表中检索唯一的行,但它只获取给定用户的用户名,而不是他的共同玩家。

    问题是如何在性能(时间)方面有效地做到这一点,并且最好不进行单独的查询?感谢。

3 个答案:

答案 0 :(得分:2)

SELECT gl.gameid, gl.type, [...], ul.userid, ul.username
FROM userlist as ul, gamelist as gl, game2users as g2u
WHERE ul.userid = g2u.userid AND
      g2u.gameid IN (SELECT gameid
                     FROM game2users
                     WHERE userid = a_certain_numeric_id);

这基本上会查找涉及给定用户的所有游戏(在子查询中),然后选择所有参与该游戏的用户。

答案 1 :(得分:1)

试试这个:

SELECT gl.gameid, gl.type, ..., ul.userid, ul.username
FROM
    (
        SELECT gameid
        FROM game2users
        WHERE userid = a_certain_numeric_id
    ) AS ug
    INNER JOIN gamelist AS gl
        ON ug.gameid = gl.gameid
    INNER JOIN game2users AS g2u
        ON ug.gameid = g2u.gameid
    INNER JOIN userlist AS ul
        ON g2u.userid = ul.userid

答案 2 :(得分:-1)

表格和关系的完整架构可以帮助我们。

我不是MySQL的专家,但似乎你可能会对数据库的不同实现感觉更好(如果你可以改变它)。现在你在games2user表中有冗余记录。我认为最简单的方法是给用户表一个包含他们所涉及的游戏的属性。然后当你对这个问题进行查询时,你可以只查询用户所参与的特定游戏的gamesTable并检索该游戏中涉及的所有用户ID。