【问题标题】:mysql select statement with multiple where/conditions具有多个 where/条件的 mysql select 语句
【发布时间】:2015-01-03 08:15:58
【问题描述】:

我在mysql中有以下两个表:

用户:

+--------+-----------+
| userId | userName  |
+--------+-----------+
| 1      | magnus    |
| 2      | f*o   |
| 3      | alexander |
| 4      | veselin   |
+--------+-----------+

游戏:

+--------+---------+---------+
| gameId | userId1 | userId2 |
+--------+---------+---------+
| 1      | 1       | 2       |
| 2      | 1       | 3       |
| 3      | 2       | 3       |
| 4      | 2       | 4       |
+--------+---------+---------+

我怎样才能构造一个单一的查询,这样我才能得到下面的输出,比如说,f*o 的对手:

输出:

+--------+-----------+
| gameId | userName  |
+--------+-----------+
| 1      | magnus    |
| 3      | alexander |
| 4      | veselin   |
+--------+-----------+

编辑1:

这是我正在尝试的,但我无法将它们放入单个查询中:

  • 选择 f*o 的对手 [select * from games where 2 in (userId1, userId2);]
  • 读取每一行,检查哪一行是f*o(2),然后选择另一个userId
  • 从这些对手的 userIds 中,从 users 表中获取他们的名字

编辑2: 受以下答案的启发,我写了这个(它们有效):

-- NO JOIN
select x.gameId, users.userName from
(
select gameId, userId2 as id from games where userId1=2
UNION
select gameId, userId1 as id from games where userId2=2 
) as x, users 
where users.userId = id;

-- NO JOIN, NO UNION        
select x.gameId, users.userName from (
SELECT g.gameId,
    CASE WHEN userId1 = 2
            THEN userId2     
         WHEN userId2 =2
            THEN userId1
         END AS id
FROM games g) as x, users
where users.userId = id;

【问题讨论】:

  • 听起来像是为我工作
  • 对不起,如果听起来是这样……请给点指示/提示?
  • 使用查询获取对手为userId1,编写相同查询获取对手为userId2,并使用联合将两个查询合并。
  • @ZeRuBuES 我不这么认为;-)

标签: mysql sql select


【解决方案1】:

您可以将这两组数据合并在一起,即 F*o 是用户 1 的所有游戏,以及他扮演用户 2 角色的所有游戏:

SELECT x.Opponent
FROM
(
    SELECT u.Name AS Opponent
    FROM games g
    INNER JOIN users u
    ON g.userId2 = u.UserId
    WHERE g.UserId1 = 2 -- F*o

    UNION

    SELECT u.Name
    FROM games g
    INNER JOIN users u
    ON g.userId1 = u.UserId
    WHERE g.UserId2 = 2 -- F*o
) AS x;

此时假设 F*o 不能同时是 User1User2,因为我们需要考虑 UNION ALL vs UNION DISTINCT :)

这也可以整理成:

SELECT x.Opponent
FROM
(
    SELECT u.Name AS Opponent, g.UserId1 AS PlayerId
    FROM games g
    INNER JOIN users u
    ON g.userId2 = u.UserId

    UNION

    SELECT u.Name, g.UserId2 AS PlayerId
    FROM games g
    INNER JOIN users u
    ON g.userId1 = u.UserId
) AS x
WHERE x.PlayerId = 2; -- F*o

【讨论】:

  • 谢谢。根据您的回答,我编写了一个简单的单一查询,对于像我这样的初学者来说相对容易阅读 - 我将其添加到我的问题中。
  • 很高兴能提供帮助。抱歉,我看到我离开了gameId
【解决方案2】:

尝试类似:

SELECT `gamess`.gameId, `users`.userName
FROM users INNER JOIN
   (SELECT gameId, userId2 as userId
    FROM games
    WHERE userId1 = 2
    UNION
    SELECT gameId, userId1 as userId
    FROM games
    WHERE userId2 = 2) AS gamess
ON `gamess`.userId = `users`.userId

【讨论】:

    【解决方案3】:

    在没有 UNION 子句的情况下这样做会提高性能

    SELECT g.gameid,
    CASE WHEN u1.userid = 2 -- fabino* 
                THEN u2.username
                else u1.username END AS Opponent
    FROM games g
    LEFT JOIN users u1
    ON g.userId1 = u1.UserId
    LEFT JOIN users u2
    on g.userid2 = u2.userid
    WHERE (g.UserId1 = 2 OR g.userid2 = 2) -- fabino
    

    【讨论】:

      【解决方案4】:

      选择我们。* 来自用户我们 内部加入游戏 gs ON us.userId = gs.userId1 GROUP BY us.userId ,us.userName

      【讨论】:

        【解决方案5】:

        此查询应该适用于所有常见的用户 ID

           SELECT x.Opponent
          FROM
          ( 
            SELECT u.userName AS Opponent
            FROM games g
            INNER JOIN users u
            ON g.userId2 = u.UserId
            WHERE g.UserId1 in (select UserId from users where UserId in (select userid1 from games)) 
            UNION
            SELECT u.userName
            FROM games g
            INNER JOIN users u
            ON g.userId1 = u.UserId
            WHERE g.UserId2 in (select UserId from users where UserId in (select userid2 from games))  
          ) AS x;
        

        【讨论】:

          最近更新 更多