2011-12-28 80 views
1

所以这里有一点关于系统的背景知识。用户的战斗和胜利者是赢得最多轮次的人。我需要帮助可能加入三张桌子。我有表user之一,它存储用户信息。表match存储匹配信息。表rounds其中每场比赛存储每场比赛的胜者,所以如果一场比赛有5场比赛,那么表rounds将有五场比赛并记录每场比赛的胜者。需要复杂查询的指导

下面是一些示例数据: 表user: (userid是主键)

userid username 
----------------- 
    1  Kevin 
    2  Sam 
    3  Steve 
    4  Matt 

match: (id是主键challengerchallenged均为外键user.userid。)

id challenger challenged rounds 
----------------------------------- 
1  2   3   3 
2  1   2   1 
3  2   3   3 
4  2   4   1 

rounds : (所有字段都是主键。 id是外键match.idwinner是外键user.userid

id round winner 
------------------ 
1 1  2 
1 2  2 
1 3  3 
2 1  1 
3 1  2 
3 2  3 
3 3  2 
4 1  4 

我试图建立一个查询,将输出下面的结果:

winner won loser won 
------------------------ 
Sam  2 Steve 1 
Kevin 1 Sam  0 
Sam  2 Steve 1 
Matt 1 Sam  0 

上述结果显示赢家每场比赛的失败者。 won字段显示分别获胜者和失败者获胜的比赛数。

有谁知道我可以如何建立上述查询?

+0

而且,这里重要的是,我认为,如果他们配合会发生什么?或者我们可以假设总会有奇数轮次? – Compeek 2011-12-28 07:58:26

+0

是的,总是有一个奇数 – user962449 2011-12-28 08:13:27

+0

我认为你应该考虑在他们发生时确定胜利并将结果存储在每场比赛的排中。因此,添加另一个字段以匹配被叫方赢家,并在匹配结束后尽快填入用户的ID。与通过巨大的查询来计算胜利相比,您可以节省大量开销,就像在每次您需要结果时看到的一些答案中一样。另外,这种方式更简单。如果这对您的项目是可行的,我觉得这是一个更好的方法。 – Compeek 2011-12-28 16:32:47

回答

1
select 
    case when w1 > w2 then u1 else u2 end as winner, 
    case when w1 > w2 then w1 else w2 end as won, 
    case when w1 > w2 then u2 else u1 end as loser, 
    case when w1 > w2 then w2 else w1 end as won 
from (
    select m.id, u1.username as u1, u2.username as u2, 
     count(r1.winner) as w1, 
     count(r2.winner) as w2 
    from match m 
    join user u1 on m.challenger = u1.userid 
    join user u2 on m.challenged = u2.userid 
    join rounds r on r.id = m.id 
    left join rounds r1 on r.id = r1.id and r.round = r1.round and r1.winner = u1.userid 
    left join rounds r2 on r.id = r2.id and r.round = r2.round and r2.winner = u2.userid 
    group by m.id, u1.username, u2.username 
) t 

它依赖于(Problems with NULL Values):

骨料(摘要)功能,诸如COUNT(),MIN()和SUM()忽略NULL值

这里是一个优点。

0

尝试:

select match_id, 
     case when challenger_wins > challenged_wins 
      then challenger_name else challenged_name end) winner, 
     case when challenger_wins > challenged_wins 
      then challenger_wins else challenged_wins end) winner_won, 
     case when challenger_wins < challenged_wins 
      then challenger_name else challenged_name end) loser, 
     case when challenger_wins < challenged_wins 
      then challenger_wins else challenged_wins end) loser_won 
from 
(select m.id match_id, 
     max(case when u.userid = m.challenger 
       then u.username end) challenger_name, 
     sum(case when u.userid = m.challenger 
       then r.wins else 0 end) challenger_wins, 
     max(case when u.userid = m.challenged 
       then u.username end) challenged_name, 
     sum(case when u.userid = m.challenged 
       then r.wins else 0 end) challenged_wins 
from match m 
join user u on u.userid in (m.challenger, m.challenged) 
left join 
(select id, winner, count(*) wins 
    from round 
    group by id, winner) r 
on m.id = r.id and u.userid = r.winner 
group by m.id) v 
0

尝试这一个 -

SELECT 
    IF(won1 >= won2, username1, username2) winner, 
    IF(won1 >= won2, won1, won2) won, 
    IF(won1 < won2, username1, username2) loser, 
    IF(won1 < won2, won1, won2) won 
FROM (
    SELECT u1.username username1, u2.username username2, COALESCE(r1.rounds, 0) won1, COALESCE(r2.rounds, 0) won2 FROM `match` m 
    JOIN user u1 
     ON u1.userid = m.challenger 
    JOIN user u2 
     ON u2.userid = m.challenged 
    LEFT JOIN (SELECT id, COUNT(round) rounds, winner FROM rounds GROUP BY id, winner) r1 
     ON r1.id = m.id AND r1.winner = u1.userid 
    LEFT JOIN (SELECT id, COUNT(round) rounds, winner FROM rounds GROUP BY id, winner) r2 
     ON r2.id = m.id AND r2.winner = u2.userid 
) t