简体   繁体   English

按两列分组,取总和,然后取最大值

[英]Group by two columns, take sum, then max

There are three columns: Id (char), Name (char), and Score (int).共有三列: Id (char)、 Name (char) 和Score (int)。

First, we group by Id and Name and add Score for each group.首先,我们按IdName分组,并为每个组添加Score Let us call the added score total_score .让我们将添加的分数total_score

Then, we group by Name and take only the maximum of total_score and its corresponding Id and Name .然后,我们按Name分组,只取total_score及其对应的IdName的最大值。 I've got everything else but I'm having a hard time figuring out how to get the Id .我拥有其他一切,但我很难弄清楚如何获得Id The error I get is我得到的错误是

Column 'Id' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause. select 列表中的“Id”列无效,因为它不包含在聚合 function 或 GROUP BY 子句中。

WITH Tmp AS
  (SELECT Id,
          Name,
          SUM(Score) AS total_score
   FROM Mytable
   GROUP BY Id,
            Name)
SELECT Name,  -- Id,
       MAX(total_score) AS max_score
FROM Tmp
GROUP BY Name
ORDER BY max_score DESC
WITH Tmp AS
  (SELECT Id,
          Name,
          SUM(Score) AS total_score
   FROM Mytable
   GROUP BY Id,
            Name)
SELECT Name,   Id,
       MAX(total_score) AS max_score
FROM Tmp
GROUP BY Name,id
ORDER BY max_score DESC

Try this.尝试这个。 Hope this will help.希望这会有所帮助。

I am not sure about performance of below query but we can use window functions to get maximum value from data partition .我不确定以下查询的性能,但我们可以使用window functions从数据partition中获取maximum

SELECT
        Id,
        Name,
        SUM(Score) AS total_score,
        MAX(SUM(Score)) OVER(Partition by Name) AS max_score
FROM Mytable
GROUP BY Id, Name;

Tested -经测试——

declare @Mytable table (id int, name varchar(10), score int);
insert into @Mytable values
(1,'abc', 100),
(2,'abc', 200),
(3,'def', 300),
(3,'def', 400),
(4,'pqr', 500);

Output - Output -

Id  Name   total_score  max_score
1   abc    100          200
2   abc    200          200
3   def    700          700
4   pqr    500          500
WITH Tmp AS
 (
 SELECT Id,
          Name,
          SUM(Score) AS total_score
   FROM Mytable
   GROUP BY Id,
            NAME
 )
SELECT Name,   Id,
       MAX(total_score) AS max_score
FROM Tmp
GROUP BY Name,id
ORDER BY max_score DESC

Note:- If we are using aggregate function then we have to use other column as Group By....注意:- 如果我们使用聚合 function 那么我们必须使用其他列作为 Group By....

In your case you are using SUM(Score) as aggregate function then we to use other column as Group by...在您的情况下,您使用 SUM(Score) 作为聚合 function 然后我们使用其他列作为 Group by...

just add row_number() partition by Name to your query and get the 1st row (order by total_score descending)只需按Namerow_number()分区添加到您的查询中并获取第一行(按total_score降序排列)

select  *
from
(
    -- your existing `total_score` query
    SELECT  Id, Name,
            SUM(Score) AS total_score,
            r = row_number() over (partition by Name order by SUM(Score) desc)
    FROM  Mytable
    GROUP BY Id, Name
) d
where   r = 1

You can select DENSE_RANK() with total_score column and then select records with Rank = 1 .您可以 select DENSE_RANK()使用total_score列,然后使用 select 记录Rank = 1 This will work for those also when there are multiple Name which are having same total_score .当有多个Name具有相同的total_score时,这也适用于那些。

WITH Tmp AS
  (SELECT Id,
          Name,
          SUM(Score) AS total_score
   FROM Mytable
   GROUP BY Id, Name)
SELECT Id, 
       Name,
       total_score AS max_score
FROM (SELECT Id, 
           Name,
           total_score,
           DENSE_RANK() OVER (PARTITION BY Name ORDER BY total_score DESC) AS Rank
    FROM Tmp) AS Tmp2
WHERE Rank = 1

You can try this as well:你也可以试试这个:

select id,name,max(total_score) over (partition by name)  max_score from (
select id,name,sum(score) as total_score from YOURTABLE
group by id,name
) t

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM