2011-12-28 2 views
1

Итак, вот немного фона в системе. Бой игрока и победитель - тот, кто выигрывает большинство раундов. Мне нужна помощь, возможно, соединяя три таблицы. У меня есть таблица user, в которой хранится информация о пользователе. Таблица match, в которой хранится информация о совпадении. Таблица rounds, которая хранит победителя каждого раунда за матч, поэтому, если матч имеет 5 раундов, то таблица rounds будет иметь пять строк для этого матча и будет записывать победителя каждого раунда.Нужно руководство для сложного запроса

Вот некоторые примерные данные: Таблицы user: (userid является первичным ключом)

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

Таблица match: (id является первичным ключом challenger и challenged являются внешними ключами к 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.id и winner является внешним ключом к 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

+0

Да, всегда есть нечетное число – user962449

+0

Думаю, вам стоит подумать о том, чтобы определить победы, как они есть, и сохранить результат в строке для каждого матча. Таким образом, добавьте другое поле для соответствия вызываемому победителю и заполните его идентификатором пользователя, как только закончится совпадение. Вы сэкономите себе много накладных расходов по сравнению с расчетом выигрышей с гигантским запросом, как в некоторых ответах, которые я вижу каждый раз, когда вам нужны результаты. Кроме того, это намного проще. Если это возможно для вашего проекта, я чувствую, что это намного лучший способ. – 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

Try:

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 
Смежные вопросы