【问题标题】:Complex IF statement with 3 tables具有 3 个表的复杂 IF 语句
【发布时间】:2012-06-12 22:55:31
【问题描述】:

这是this question from yesterday 的延续。

这是我的三张桌子:

格斗桌

fighter_id |  name
-----------------------
1          | John
2          | Steve
3          | Bill
4          | Bobby

事件表

event_id  |  event_name  |  event_date
-------------------------------------------
1          | MMA         |  01/01/2010
2          | Cool        |  02/20/2010
3          | Yeaa!       |  04/15/2010

格斗桌

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  |  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

所以在fights表中,fighter_a、fighter_b和winner是对应于Fighters表中的fighter_id的整数。

我基本上是在基于 fighter_id ($fighter_id) 检索数据的页面上。

我正在尝试为该战士的每场战斗创建行,其中包括他的对手的名字、结果(胜利、失败、平局或 nc)、方法、事件名称和事件日期。挑战在于获胜者可以在 fighter_a 或 fighter_b 中。它并不总是在同一列中。我很感激能得到任何帮助。

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

【问题讨论】:

  • 事件表没有连接。您如何在 event_date 之前订购?
  • 呃,是的,对不起。这是一种痛苦。我的三个主表设置正确吗?现在检索这些数据似乎是一个 PITA。 :(

标签: mysql relational-database relational


【解决方案1】:

使用带有条件的子选择将您要查找的 fighter_id 切换到 column_a(如果它在 column_b 中),这样可以简化您的操作并加入外部查询:

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

此外,如果获胜者字段为空,则只需回显方法字段。这样,当您想在系统中添加另一种获胜者为空的方法时,您不必继续对 CASE 语句进行更多条件检查。

【讨论】:

  • 谢谢,这会返回You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CASE ) AS result, b.name AS opponent, a.method AS method, c.' at line 7
  • 好的,已修复。现在试试,END CASE 应该只是END
  • 天哪,你摇滚!非常感谢伙计。以及此线程中的其他所有人。很难想象这一点。我会继续努力学习的。 :)
【解决方案2】:

你可以使用联合:

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

【讨论】:

  • 返回Unknown column 'participant_id' in 'field list'
  • @zen 对不起,我看错了问题; participant_id 应该是 fighter_aopponent_id 应该是 fighter_b
【解决方案3】:

您可以修改 CASE 语句以匹配 $fighter_id

所以你的 CASE 语句将是 -

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)

【讨论】:

  • 嗯,我收到一个 SQL 错误 Table 'mma.fighter' doesn't exist。请注意, mma 是数据库的名称。原表都不应该在 FROM 中吗?
  • 有一个错字。写了fighter 而不是fighters
  • 现在我得到Notice: Trying to get property of non-object in C:\xampp\htdocs\fighter-detail.php on line 124 这就是我尝试使用 PHP 提取信息的方式。第 124 行是 echo match_result。 while($row = mysql_fetch_array($get_all_fighter_fights)) { echo "&lt;tr&gt;"; echo "&lt;td&gt;" . $row-&gt;match_result . "&lt;/td&gt;"; echo "&lt;/tr&gt;"; }
  • @zen 您收到该错误是因为 $row 不是对象,但您正在使用对象语法尝试从中获取 match_result 。关联数组的正确语法是 $row['match_result']
  • 啊,我明白了。这确实解决了它。嗯,我需要了解差异。
【解决方案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

【讨论】:

  • 这也返回Notice: Trying to get property of non-object in C:\xampp\htdocs\fighter-detail.php on line 128。第 128 行只是使用 $row-&gt;result 从数组中取出行
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-06
  • 2017-05-28
  • 2022-01-03
相关资源
最近更新 更多