2011-12-28 14 views
1

システムの背景を少し説明します。ユーザーの戦いと勝者は最も多くのラウンドを勝ち取った人です。私はおそらく3つのテーブルに参加して助けが必要です。私はユーザ情報を格納するテーブルuserを持っています。一致情報を格納するテーブルmatch。テーブルroundsには1試合ごとの勝者が格納されています。したがって、試合のラウンドが5ラウンドの場合、テーブルroundsはその試合に5つの行を持ち、各ラウンドの勝者を記録します。複雑なクエリのガイダンスが必要

ここではいくつかのサンプルデータがあります: 表user: (useridが主キーである)

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

match: (idが主キーですchallengerchallengeduser.useridへの外部キーの両方である。)

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

rounds : (すべてのフィールドが主キーです。

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

上記の結果は、勝者を示し、:idmatch.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 

Iの出力は以下となり、次の結果がクエリを構築しようとしているです各試合の敗者。 wonフィールドには、勝者と敗者それぞれの試合で獲得したラウンド数が表示されます。

私は上記のクエリをどのように構築できるか知っていますか?

+0

ここで重要なのは、私が思うに、彼らはネクタイとどうなるかですか?あるいは、常に奇数のラウンドがあると仮定することができますか? – Compeek

+0

はい、いつも奇数があります – user962449

+0

私は勝ちを決めることを検討し、各試合の行に結果を格納することを検討するべきだと思います。だから、勝者と呼ばれる別のフィールドを追加し、マッチが終わるとすぐにユーザーのIDでそれを記入してください。あなたは結果が必要なたびに私が見ている回答のいくつかのような巨大なクエリで勝利を計算するのと比較して、オーバーヘッドを大幅に節約できます。さらに、それはずっと簡単です。それがあなたのプロジェクトにとって実現可能なら、私はそれがもっと良い方法だと思っています。 – Compeek

答えて

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

は試してみてください、この1 -

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