需要复杂查询的指导

时间:2011-12-28 07:45:21

标签: mysql sql join

所以这里有一个关于系统的小背景。用户的战斗和胜利者是赢得最多轮次的人。我需要帮助才能加入三张桌子。我有一个表user,用于存储用户信息。存储匹配信息的表match。表rounds存储每场比赛的每轮比赛的获胜者,因此如果比赛有5轮,那么表rounds将有五行用于该比赛,并将记录每轮的获胜者。

以下是一些示例数据: 表格1}}: (user是主键)

userid

userid username ----------------- 1 Kevin 2 Sam 3 Steve 4 Matt : (match是主键。idchallenger都是challenged的外键。

user.userid

id challenger challenged rounds ----------------------------------- 1 2 3 3 2 1 2 1 3 2 3 3 4 2 4 1 : (所有字段都是主键。roundsid的外键,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 字段分别显示赢家和输家的赢得的回合数。

有谁知道如何构建上述查询?

3 个答案:

答案 0 :(得分: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值

这是一个优势。

答案 1 :(得分: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

答案 2 :(得分: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