3

I have the following two tables in mysql:

users:

+--------+-----------+
| userId | userName  |
+--------+-----------+
| 1      | magnus    |
| 2      | fabiano   |
| 3      | alexander |
| 4      | veselin   |
+--------+-----------+

games:

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

How can I construct a single query such that I get this below output of say, fabiano's opponents:

output:

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

Edit1:

This was what I was trying and I wasn't able to get them into a single query:

  • select fabiano's opponents [select * from games where 2 in (userId1, userId2);]
  • read each of the rows, and check which of them is fabiano(2), and select the other userId
  • from the userIds of these opponents, get their name from users table

Edit2: Inspired by the answers below, I wrote this (they work):

-- 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;
4
  • sounds like do my work for me Commented Jan 3, 2015 at 8:18
  • sorry if it sounds so ... any directions/hints please ? Commented Jan 3, 2015 at 8:19
  • 1
    Use a query to get opponents as userId1, write the same query to get opponents as userId2, and use a union to combine the two queries. Commented Jan 3, 2015 at 8:20
  • @ZeRuBuES I don't think so ;-) Commented Jan 3, 2015 at 9:38

5 Answers 5

4

You can union the two sets of data together, viz all games where Fabiano is User 1, with all games that he is in the role of User 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 -- Fabiano

    UNION

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

At this point as assume that Fabiano can't simultaneously both be User1 and User2, as we would need to consider UNION ALL vs UNION DISTINCT :)

This could also be tidied up a bit into:

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; -- Fabiano
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks. Based on your answer, I wrote a simple, single query which is relatively easy for a beginner like me to read - I'm adding it to my question.
Glad to be of help. Apologies, I see I left off gameId
2

Try something like:

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

Comments

1

Doing this without a UNION clause will make it more performant

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

Comments

0

SELECT us.* FROM users us INNER JOIN games gs ON us.userId = gs.userId1 GROUP BY us.userId ,us.userName

Comments

0

This query should be works all of common userid

   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;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.