根据同一个表中的两列选择单列的总和

时间:2011-10-24 01:44:37

标签: mysql sql select aggregate-functions

我的桌子与下面的桌子很相似。表格中的p1p2是指另一张桌子上玩家的ID。

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

我想要做的是获得得分最高的玩家ID(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 个答案:

答案 0 :(得分:4)

您可以将玩家放在一列中:

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

现在,你说你也想知道玩家玩了多少次并按降序排序:

select sum(score), player, count(*) as timesPlayed from (
    select id, score, p1 as player, date from yourtable
    union all
    select id, score, p2 as player, date from yourtable
) group by player order by sum(score) desc

答案 1 :(得分:2)

尝试此操作以获得得分最高的玩家(无视关系)

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

要获得玩家总分,请尝试此

select Player as pID,Sum(tot) as Score, count(*) as TimesPlayed
from
(
select p1 as Player,sum(score) as Tot
from table 
group by p1
union all
select p2,sum(score)
from table 
group by p2
) xx
Group by xx.Player
order by Score desc

答案 2 :(得分:1)

除了在桌子上使用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