Выбор суммы одного столбца в зависимости от двух столбцов в одной таблице - PullRequest
3 голосов
/ 24 октября 2011

У меня есть таблица, очень похожая на приведенную ниже.p1 и p2 на столе означают идентификатор игрока за другим столом.

id score p1 p2 date
-- ----- -- -- ----
1  12    1  2  2011.10.21
2  23    3  4  2011.10.22
3  21    1  3  2011.10.23
4  35    5  1  2011.10.24
5  11    2  3  2011.10.25

Я хочу получить идентификатор игрока (p1 или p2) с наибольшим количеством очков.Мое решение - что-то вроде select sum(score), но я не могу сформировать запрос, потому что игрок может появиться как в столбцах p1, так и в столбце p2.

Также большая проблема возникает, когда я хочу отсортировать баллы по возрастанию и убыванию.Я не знаю что делать.Как можно суммировать и сортировать баллы, если мне нужно сгруппировать в отдельные столбцы?Результат, который я хочу, похож на этот результат:

pID score times_played
--- ----- ------------
1   68    3
3   55    3
5   35    1
2   23    2
4   23    1

Является ли мой дизайн базы данных некорректным?Если есть более разумный способ, я бы хотел знать.Нужно ли мне отдельные запросы, чтобы я мог объединить их на PHP или что-то еще?

Буду признателен за любую помощь.Приветствия.

PS: Я не мог придумать хороший предмет.Не стесняйтесь редактировать.

Ответы [ 3 ]

4 голосов
/ 24 октября 2011

Вы можете поместить игроков в один столбец следующим образом:

select id, score, p1 as player, date from yourtable
union all
select id, score, p2 as player, date from yourtable

Теперь у вас есть игроки в одном столбце.Вы можете сделать это, чтобы получить сумму очков для всех игроков

select sum(score), player from (
    select id, score, p1 as player, date from yourtable
    union all
    select id, score, p2 as player, date from yourtable
) group by player

Теперь вы говорите, что вы также хотите знать, сколько раз игрок играл, и сортировать их по убыванию:

2 голосов
/ 24 октября 2011

Попробуйте, чтобы получить игроков с наибольшим количеством очков (без учета связей)

select id,p1,p2 
from table t1
join (select max(score) as MaxS) xx on xx.MaxS = t1.Score
limit 1

Чтобы получить общий счет игрока, попробуйте это

1 голос
/ 24 октября 2011

Вместо использования UNION (ALL) в таблице вы можете попробовать что-то вроде этого:

SELECT
  CASE p.PlayerNumber WHEN 1 THEN t.p1 ELSE t.p2 END AS pID,
  SUM(t.score) AS score,
  COUNT(*) AS times_played
FROM atable t
  CROSS JOIN (SELECT 1 AS PlayerNumber UNION ALL SELECT 2) p
GROUP BY
  pID /* this is probably MySQL-specific; most, if not all, other major
database systems would require repeating the entire pID expression here, i.e.
GROUP BY
  CASE p.PlayerNumber WHEN 1 THEN t.p1 ELSE t.p2 END
*/
ORDER BY
  score DESC,
  times_played DESC  /* this is based on your result set;
                        you might want to omit it or change it to ASC */

ОБНОВЛЕНИЕ , в ответе на вопрос в комментариях: присоединение результирующего набора к таблице user:

SELECT
  `user`.*,  /* you should probably specify
                the necessary columns explicitly */
  totals.score,
  totals.times_played
FROM `user` u
  INNER JOIN (
    SELECT
      CASE p.PlayerNumber WHEN 1 THEN t.p1 ELSE t.p2 END AS pID,
      SUM(t.score) AS score,
      COUNT(*) AS times_played
    FROM atable t
      CROSS JOIN (SELECT 1 AS PlayerNumber UNION ALL SELECT 2) p
    GROUP BY
      pID
  ) totals ON user.id = totals.pID
ORDER BY
  totals.score DESC,
  totals.times_played DESC
...