【问题标题】:Getting data from a table meeting some requirements从满足某些要求的表中获取数据
【发布时间】:2016-03-14 20:42:47
【问题描述】:

我遇到了一个 SQL 逻辑问题。 我有一个“游戏”表,其中包含一些数据,其中 player1_id 和 player2_id 是在跳棋比赛中相互玩的用户 ID:

每个游戏都以不同的环境开始,已经在另一个表中指定(由“game_id”列键控)。 假设每个人都在线,用户不能重玩同一个游戏。 如何只选择没有玩过我还没有玩过的游戏的用户来匹配我? AJAX 调用将匹配尚未玩过特定游戏的两个用户并让他们玩。 无论用户是 player1 还是 player2 ,他都不能重复游戏。 非常感谢。

表格:

game_match

+----+---------+------------+------------+
| id | game_id | player1_id | player2_id |
+----+---------+------------+------------+
|  1 |       1 |         16 |         17 |
|  2 |       1 |         18 |         23 |
|  3 |       1 |         19 |         21 |
|  4 |       1 |         20 |         22 |
|  5 |       2 |         20 |         17 |
|  6 |       2 |         16 |         18 |
|  7 |       2 |         19 |         23 |
|  8 |       1 |         25 |         15 |
+----+---------+------------+------------+

用户

+----+-----------+
| id | name      |
+----+-----------+
| 17 | Donald    |
| 18 | Margarida |
| 19 | Daisy     |
| 20 | Mickey    |
| 21 | Steve     |
| 22 | Raul      |
| 23 | Janis     |
| 24 | Michael   |
| 25 | Sergio    |
| 26 | Bill      |
| 27 | Alina     |
| 28 | Alana     |
| 29 | Harumi    |
| 30 | Danielle  |
| 31 | Lisa      |
+----+-----------+

谢谢!

【问题讨论】:

  • 为什么你有一个名为games 的表,其中game_id不是唯一的主键?
  • 已编辑。抱歉,表名错误。表“游戏”是带有游戏场景的表。
  • 你能提供一些例子来说明你的意思吗?你的任务很难解析。

标签: mysql sql subquery logic


【解决方案1】:

假设您有一个名为 games 和一个 $userid 的表,您可以使用 not exists 轻松完成此操作:

select g.*
from games g
where not exists (select 1 
                  from game_match gm 
                  where gm.game_id = g.game_id and gm.player1_id = $userid
                 ) or
      not exists (select 1 
                  from game_match gm 
                  where gm.game_id = g.game_id and gm.player2_id = $userid
                 ) ;

请注意,您可以使用or 和一个子查询来实现相同的逻辑。但是,使用正确的索引,两个子查询效率更高。

【讨论】:

  • 感谢您的回答。通过这个查询,我得到了我已经玩过的游戏。
  • @Alrogatto 。 . .我想我误解了你的问题。
  • 对不起,我在压力下有点困惑。哈哈。不过谢谢!我现在明白了,你帮了我很多。
【解决方案2】:

为了获得您的用户,我会在子查询中使用联合:

select * 
from users 
where id not in 
   (select player1_id as played
    from game_match 
    where player2_id = @logged_in_user
    union
    select player2_id 
    from game_match 
    where player1_id = @logged_in_user
    ) as played

【讨论】:

  • 感谢您的回答。但是通过这个查询,我得到了我已经玩过的游戏。
  • 这个查询应该返回所有你还没有玩过的用户。它获取您玩过的所有用户,然后从用户表中选择所有不是他们的用户。您在这里的预期输出是什么?
【解决方案3】:

使用 NOT EXISTS 和 INNER JOIN 尝试以下解决方案:

select name
from Users AS u
where not exists(
    select 1 
    from game_match AS gm INNER JOIN
    (select distinct game_id 
     from game_match
     where @current_user_id = player1_id OR @current_user_id = player2_id) gids
        USING(game_id)
    where u.id = gm.player1_id OR u.id = gm.player2_id
    );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 2021-08-02
    • 1970-01-01
    • 2021-10-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多