将子查询添加到已经很大的查询中

时间:2012-07-05 00:35:42

标签: mysql relational-database relational

这个问题是我一个月前问过的this question的后续问题。

这是我的三张桌子。

战斗机

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

我想要两个额外的列。一个用于战斗机的记录,一个用于他的对手记录,两者都基于事件的日期。因此,记录到该日期并包括该日期,但不能超过该日期。基本上< =到当前行的日期。

期望的结果

result  | record   |  opponent  | opp. record |  method  | event  |  date        
-----------------------------------------------------------------------------
Draw    | 1-1-1    | Bill       |  0-0-1      |  Draw    | Yeaa!  |  04/15/2010  
Loss    | 1-1      | Bobby      |  1-0        |  KO      | Cool   |  02/20/2010 
Win     | 1-0      | Steve      |  0-1        |  Sub     | MMA    |  01/01/2010

所以这是获取当前结果的代码:

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,
    b.fighter_id AS opponent_id,
    b.fighting_out_of_country AS opponent_country,
    a.method AS method,
    a.method_type AS method_type,
    a.round AS round,
    a.time AS time,
    c.event_id AS event_id,
    c.event_name AS event,
    c.event_date AS date,
    c.event_city AS event_city,
    c.event_state AS event_state,
    c.event_country AS event_country
FROM
    (
        SELECT 
            IF(fighter_b = :fighter_id_0, fighter_b, fighter_a) AS f_a,
            IF(fighter_b = :fighter_id_1, fighter_a, fighter_b) AS f_b,
            winner,
            method,
            method_type,
            round,
            time,
            event
        FROM 
            fights
        WHERE
            :fighter_id_2 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

这是我用来获得一个战斗机记录的查询,但我不确定如何将它集成到这个主要查询中以获取战斗机和对手的记录。当然我最终得到4个值,所以我可以用PHP和HTML / CSS来操作它们。 (胜/损失/平/ no_contests)

SELECT 
SUM(if(winner = :fighter_id_3, 1, 0)) AS wins,
SUM(if(winner <> :fighter_id_4, 1, 0)) AS losses,
SUM(if(method = "Draw", 1, 0)) AS draws,
SUM(if(method = "No Contest", 1, 0)) AS no_contests

FROM fights
WHERE :fighter_id_5 IN (fighter_a, fighter_b) 

1 个答案:

答案 0 :(得分:2)

试试这个:

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,
    SUM(a.f_a IN (d.fighter_a, d.fighter_b) AND d.winner <=> a.f_a) AS fighter_wincount,
    SUM(a.f_a IN (d.fighter_a, d.fighter_b) AND d.winner IS NOT NULL AND d.winner <> a.f_a) AS fighter_losscount,
    SUM(a.f_a IN (d.fighter_a, d.fighter_b) AND d.method = 'Draw') AS fighter_drawcount,
    SUM(a.f_a IN (d.fighter_a, d.fighter_b) AND d.method = 'No Contest') AS fighter_nocontestcount,
    b.name AS opponent,
    SUM(a.f_b IN (d.fighter_a, d.fighter_b) AND d.winner <=> a.f_b) AS opponent_wincount,
    SUM(a.f_b IN (d.fighter_a, d.fighter_b) AND d.winner IS NOT NULL AND d.winner <> a.f_b) AS opponent_losscount,
    SUM(a.f_b IN (d.fighter_a, d.fighter_b) AND d.method = 'Draw') AS opponent_drawcount,
    SUM(a.f_b IN (d.fighter_a, d.fighter_b) AND d.method = 'No Contest') AS opponent_nocontestcount,
    b.fighter_id AS opponent_id,
    b.fighting_out_of_country AS opponent_country,
    a.method AS method,
    a.method_type AS method_type,
    a.round AS round,
    a.time AS time,
    c.event_id AS event_id,
    c.event_name AS event,
    c.event_date AS date,
    c.event_city AS event_city,
    c.event_state AS event_state,
    c.event_country AS event_country
FROM
    (
        SELECT 
            fight_id,
            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,
            method_type,
            round,
            time,
            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
LEFT JOIN
    (
        SELECT 
            a.fighter_a,
            a.fighter_b,
            a.winner,
            a.method,
            b.event_date
        FROM
            fights a
        INNER JOIN
            events b ON a.event = b.event_id
    ) d ON 
        (a.f_a IN (d.fighter_a, d.fighter_b) OR a.f_b IN (d.fighter_a, d.fighter_b)) AND
        d.event_date < c.event_date
GROUP BY
    a.fight_id
ORDER BY
    c.event_date DESC