Mysql,在多个表中搜索

时间:2013-05-31 18:45:29

标签: mysql

我正在开发异步游戏,但我对MySQL和PHP完全不熟悉。我有两个表,tb_users和tb_matches。第一个存储所有用户及其状态(例如,'status'列中的值0表示玩家处于待机状态,而值1表示玩家正在等待对手进行比赛) 。

tb_matches表存储所有匹配项,包括活动和非活动(已完成)匹配项。此表中有两列包含玩家ID。

我要做的是搜索一个必须满足这些要求的可用对手:

1)tb_users表中的状态必须为1 2)它必须与搜索新对手的用户没有主动匹配

我试过了:

SELECT * 
FROM tb_users
JOIN tb_matches
WHERE tb_users.status = "1"
AND tb_matches.player1 != '".$username."'
AND tb_matches.player2 != '".$username."'

..但它没有给我任何结果。此外,它应该考虑到在tb_matches表中,可能根本没有匹配。

有任何帮助吗?此外,还有更好的方法来完成这项任务吗?

3 个答案:

答案 0 :(得分:1)

考虑以下备用表结构:

tb_users
---------
id
name
seeking


tb_user_matches
---------------
match_id
player_id


tb_matches
----------
id
started
ended
status
  • 添加第三个(多对多)表来存储哪些玩家参与哪个匹配允许更简单的查询,请参阅下文。
  • tb_users中的“状态”更改为“搜索”,以便布尔数据类型有意义。
  • 请勿在{{1​​}}中存储播放器名称,并存储其ID。 (允许更改名称而不破坏链接(Normalization)。)
  • 考虑将日期时间字段添加到tb_matches以存储匹配开始和结束日期;它可能在将来有用。
  • tb_matches中的“状态”列可以指示三种匹配状态:等待更多玩家,正在进行或已完成(见下文)。

使用此结构,您可以使用以下查询来查找以下内容:

  • 搜索匹配(搜索= 1)
  • 尚未参加等待球员的比赛

tb_matches

我建议SELECT u.id, u.name FROM tb_users u LEFT JOIN tb_user_matches um JOIN tb_matches m ON um.match_id = m.id AND m.status = 0 ON u.id = um.player_id WHERE u.seeking = 1 AND um.match_id IS NULL; 为非活动状态(等待玩家)为“0”,活动为“1”,完成为“2”。

这不一定检查玩家是否已经参加了主动比赛。也许你的游戏允许玩家参加多个同步比赛?如果没有,您可以更改查询以排除有效的匹配项(将tb_matches.status更改为m.status = 0)。

修改

用英语解释查询(尽我所能):

从users表中选择用户ID和名称。在匹配状态为“0”(等待)的位置包括用户所涉及的匹配项。 (m.status != 2使得如果用户没有参与任何状态为“0”的匹配,则match_id将为空(null)。)

现在,从这组数据中,只显示正在寻找(LEFT JOIN)且未处于等待匹配(u.seeking = 1)的用户。

答案 1 :(得分:0)

试试这个(请注意,您必须将'username'替换为实际用户名)

SELECT * 
FROM tb_users 
WHERE Username != 'username'
AND status = 1 
AND NOT EXISTS (SELECT * 
                FROM tb_matches 
                WHERE (player1 = 'username' OR player2 = 'username')
                AND Status = 'inactive')

答案 2 :(得分:-1)

SELECT * 
FROM
    `tb_users`
WHERE
    `tb_users`.`status` = "1"
AND
    `tb_users`.`name` NOT IN (
        SELECT `player1` FROM `tb_matches` WHERE `player2` = 'username'
        UNION
        SELECT `player2` FROM `tb_matches` WHERE `player1` = 'username'
        UNION
        SELECT 'username'
    )