问题
This is a continuation of this question from yesterday.
Here are my three tables:
Fighters Table
fighter_id | name
-----------------------
1 | John
2 | Steve
3 | Bill
4 | Bobby
Events Table
event_id | event_name | event_date
-------------------------------------------
1 | MMA | 01/01/2010
2 | Cool | 02/20/2010
3 | Yeaa! | 04/15/2010
Fights Table
fight_id | fighter_a | fighter_b | winner | method | event
-----------------------------------------------------------------------
1 | 1 | 2 | 1 | Sub | 1
2 | 4 | 1 | 4 | KO | 2
3 | 1 | 3 | NULL | Draw | 3
Result trying to get
result | opponent | method | event | date
----------------------------------------------------------
Draw | Bill | Draw | Yeaa! | 04/15/2010
Loss | Bobby | KO | Cool | 02/20/2010
Win | Steve | Sub | MMA | 01/01/2010
So in the fights table, fighter_a, fighter_b, and winner are integers that correspond to fighter_id in the Fighters table.
I'm basically on a page retrieving data based on fighter_id ($fighter_id).
I'm trying to create rows with each fight of that fighter that includes his opponent's name, result (win, loss, draw, or nc), method, event_name, and event_date. The challenge is that a winner can be in either fighter_a or fighter_b. It's not always in the same column. I appreciate any help I can get.
select
fight_id,
CASE
WHEN winner is not null and winner=fighter_id then 'win'
WHEN winner is not null and winner<>fighter_id then 'loss'
WHEN winner is null and method='Draw' then 'draw'
WHEN winner is null and method = 'No Contest' then 'no contest'
ELSE ''
END as match_result,
participant.name 'participant',
opponent.name 'opponent'
FROM fights
INNER JOIN fighters as participant on participant.fighter_id = fights.fighter_a
INNER JOIN fighters as oppoent on opponent.fighter_id = fights.fighter_b
WHERE
fighter_a=$fighter_id OR fighter_b=$fighter_id
ORDER BY
event_date DESC
回答1:
Use a subselect with conditionals to switch the fighter_id you're looking for to column_a if it's in column_b, that way, it simplifies your operations and joins in the outer query:
SELECT
(
CASE
WHEN a.winner = a.f_a THEN 'Win'
WHEN a.winner = a.f_b THEN 'Loss'
WHEN a.winner IS NULL THEN a.method
END
) AS result,
b.name AS opponent,
a.method AS method,
c.event_name AS event,
c.event_date AS date
FROM
(
SELECT
IF(fighter_b = $fighter_id, fighter_b, fighter_a) AS f_a,
IF(fighter_b = $fighter_id, fighter_a, fighter_b) AS f_b,
winner,
method,
event
FROM
fights
WHERE
$fighter_id IN (fighter_a, fighter_b)
) a
INNER JOIN
fighters b ON a.f_b = b.fighter_id
INNER JOIN
events c ON a.event = c.event_id
ORDER BY
c.event_date DESC
Also, if the winner field is null, then just echo the method field. That way, when you want to add yet another type of method where winner is null to your system, you don't have to keep tacking on more conditional checks to your CASE
statement.
回答2:
You could use a union:
SELECT CASE WHEN winner = participant_id THEN 'Win'
WHEN winner = opponent_id then 'Loss'
ELSE method
END AS result, fighters.name AS opponent, method, event_name, event_date
FROM fights
INNER JOIN fighters ON fighter_id = opponent_id
INNER JOIN events ON event = event_id
WHERE participant_id = $fighter_id
UNION ALL
SELECT CASE WHEN winner = participant_id THEN 'Loss'
WHEN winner = opponent_id then 'Win'
ELSE method
END AS result, fighters.name AS opponent, method, event_name, event_date
FROM fights
INNER JOIN fighters ON fighter_id = participant_id
INNER JOIN events ON event = event_id
WHERE opponent_id = $fighter_id
ORDER BY event_date DESC
回答3:
You could just modify you CASE
statements to match with $fighter_id
.
So your CASE
statements would be -
select fight_id,
CASE
WHEN winner is not null and winner = f.fighter_id then 'win'
WHEN winner is not null and winner <> f.fighter_id then 'loss'
WHEN winner is null and method='Draw' then 'draw'
WHEN winner is null and method = 'No Contest' then 'no contest'
ELSE ''
END as match_result,
f.name AS participant,
(SELECT o.name FROM fighters o WHERE o.fighter_id = IF(f.fighter_id = fs.fighter_a, fs.fighter_b, fs.fighter_a)) AS opponent
FROM fights fs,
fighters f
WHERE f.fighter_id = $fighter_id
AND (fs.fighter_a = f.fighter_id OR fs.fighter_b = f.fighter_id)
回答4:
SELECT
CASE
WHEN winner is not null and winner=fighter_id then 'win'
WHEN winner is not null and winner<>fighter_id then 'loss'
WHEN winner is null and method='Draw' then 'draw'
WHEN winner is null and method = 'No Contest' then 'no contest'
ELSE ''
END result,
f2.name opponent,
method,
event_name event,
event_date date
FROM fights f1
INNER JOIN fighters f2
ON f1.fighter_b = f2.fighter_id
INNER JOIN events e
ON e.event_id = f1.event
ORDER BY date DESC
来源:https://stackoverflow.com/questions/11006025/complex-if-statement-with-3-tables