选择最大的总和,但结果中没有总和

时间:2015-10-21 03:51:17

标签: sql postgresql sum aggregate-functions window-functions

我需要选择玩家所有组合尝试的最高分,我需要使用WITH条款。

create table scorecard(
 id integer primary key,
 player_name varchar(20));

create table scores(
 id integer references scorecard,
 attempt integer,
 score numeric
 primary key(id, attempt));

记分卡的示例数据:

id       player_name
1        Bob      
2        Steve    
3        Joe    
4        Rob    

分数的示例数据:

id    attempt    score
1        1         50
1        2         45
2        1         10
2        2         20
3        1         40
3        2         35
4        1         0
4        2         95

结果将如下所示:

player_name
Bob
Rob

但如果罗布的得分低于95,那只会是鲍勃。我已经得到了他们在两列中得到的名称和总分数:

select scorecard.player_name, sum(scores.score)
from scorecard
left join scores
on scorecard.id= scores.id
group by scorecard.name
order by sum(scores.score) desc;

但是我如何得到最高分的名字(或者如果并列则得分)。

请记住,它应该使用a WITH子句。

3 个答案:

答案 0 :(得分:1)

曾经告诉过你“使用WITH子句”的人错过了一个更有效的解决方案。要获得(可能是多个)获胜者:

SELECT c.player_name
FROM   scorecard c
JOIN  (
   SELECT id, rank() OVER (ORDER BY sum(score) DESC) AS rnk
   FROM   scores
   GROUP  BY 1
   ) s USING (id)
WHERE  s.rnk = 1;

普通子查询通常比CTE更快。如果必须使用WITH子句:

WITH top_score AS (
   SELECT id, rank() OVER (ORDER BY sum(score) DESC) AS rnk
   FROM   scores
   GROUP  BY 1
   )
SELECT c.player_name
FROM   scorecard c
JOIN   top_score s USING (id)
WHERE  s.rnk = 1;

SQL Fiddle.

可以添加最终ORDER BY c.player_name以获得稳定的排序顺序,但不会请求。

查询的关键功能是您可以对聚合函数的结果运行window function like rank()。相关:

答案 1 :(得分:0)

可以尝试以下内容。

With (SELECT id, sum(score) as sum_scores
      FROM scores
      group by id) as sumScoresTable,

With (SELECT max(score) as max_scores
      FROM scores
      group by id) as maxScoresTable

select player_name 
FROM scorecard
WHERE scorecard.id in (SELECT sumScoresTable.id 
                       from sumScoresTable 
                       where  sumScoresTable.score = (select maxScoresTable.score from maxScoresTable)

答案 2 :(得分:0)

试试这段代码:

   WITH CTE AS (
       SELECT ID, RANK() OVER(ORDER BY SumScore DESC) As R
       FROM (
          SELECT ID, SUM(score) AS SumScore
          FROM scores
          GROUP BY ID )
    )

   SELECT player_name
   FROM scorecard
   WHERE ID IN (SELECT ID FROM CTE WHERE R = 1)