Reputation: 4125
I have following database schema:
Players table:
| player_id |
|-----------|
| 1 |
| 2 |
| 3 |
| 4 |
| ... |
Games table:
| game_id | white_player_id | black_player_id | game_status |
|----------|-----------------|-----------------|-------------|
| 1 | 1 | 2 | in progress |
| 2 | 3 | 4 | in progress |
| 3 | 5 | 6 | white won |
| 4 | 1 | 3 | draw |
| ... | ... | ... | ... |
I want to select all players, who are not currently playing.
I tried to achieve it in the following way, but it does not work as i expect.
SELECT player.player_id
FROM players
LEFT JOIN games g1
ON players.player_id = g1.white_player_id
LEFT JOIN games g2
ON players.player_id = g2.black_player_id
WHERE
g1.white_player_id IS NULL AND
g1.game_status NOT IN ('in progress') OR
g2.white_player_id IS NULL AND
g2.game_status NOT IN ('in progress')
Any help would be greatly appreciated.
Upvotes: 0
Views: 1518
Reputation: 20794
When you do this:
select *
from t1 left join t2 on something
WHERE t2.someField = someValue
AND other conditions
You effectively convert the left join to an inner join. To filter on the outer joined table, do so in the from clause.
select *
from t1 left join t2 on something
AND t2.someField = someValue
WHERE other conditions
Upvotes: 0
Reputation: 72165
Try this:
SELECT player_id
FROM players
WHERE player_id NOT IN (
SELECT white_player_id
FROM games
WHERE game_status IN ('in progress')
UNION ALL
SELECT black_player_id
FROM games
WHERE game_status IN ('in progress'))
This query selects all players not participating in games with a game_status
equal to 'in progress'
.
Upvotes: 2