1

我正在开发一个异步游戏,但我对 MySQL 和 PHP 完全陌生。我有两个表,tb_users 和 tb_matches。第一个存储所有用户及其状态(例如,“状态”列中的值为 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 表中可能根本没有匹配项。

有什么帮助吗?另外,有没有更好的方法来完成这项任务?

4

3 回答 3

1

考虑以下替代表结构:

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


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


tb_matches
----------
id
started
ended
status
  • 添加第三个(多对多)表来存储哪些球员参与了哪场比赛,这允许更简单的查询,见下文。
  • 将“状态”更改tb_users为“正在寻找”,这样布尔数据类型才有意义。
  • 不要将玩家姓名存储在 中tb_matches,存储他们的 ID。(允许在不中断链接的情况下更改名称(规范化)。)
  • 考虑添加日期时间字段来tb_matches存储比赛开始和结束日期;将来可能会有用。
  • 中的“状态”列tb_matches可以指示三种比赛状态:等待更多玩家、进行中或完成(见下文)。

使用此结构,您可以使用以下查询来查找以下玩家:

  • 搜索匹配项(搜索 = 1)
  • 尚未在等待玩家的比赛中

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;

我建议tb_matches.status可能是“0”表示不活动(等待玩家),“1”表示活动,“2”表示已完成。

这并不一定检查玩家是否已经参与了活跃的比赛。也许您的游戏允许玩家同时参加多个比赛?如果没有,您可以更改查询以排除也处于活动状态的匹配项(更改m.status = 0m.status != 2)。

编辑:

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

从 users 表中选择用户 ID 和名称。包括用户参与其中匹配状态为“0”(等待)的匹配。(LEFT JOIN如果用户没有参与任何状态为“0”的匹配,则 match_id 将为空(null)。)

现在,从这组数据中,只显示正在寻找的用户(u.seeking = 1),而不是等待匹配的用户(um.match_id IS NULL)。

于 2013-05-31T19:01:40.790 回答
0

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

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')
于 2013-05-31T18:54:57.820 回答
-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'
    )
于 2013-05-31T18:50:49.440 回答