汇总查询中的非分组列

时间:2019-04-11 01:59:06

标签: sql sql-server

说我有一个包含三列的表:c1c2c3。我想在每个c1中获得c2的最大值和包含最大值的行的c3的值。

这是一个例子。说MyTable包含以下记录:

c1   c2   c3
---  ---  ---
1    32   12
1    27   15
1    12   21
2    23   33
2    36   49
3    48   17
3    21   50
3    7    25

然后我的查询应该返回

c1   MAX(c2)  c3
---  -------  ---
1    32       12
2    36       49
3    48       17

但是当我查询

SELECT c1, MAX(c2), c3 FROM MyTable GROUP BY c1

我得到了错误:

Column 'MyTable.c3' is invalid in the select list because it is not 
contained in either an aggregate function or the GROUP BY clause.

如何解决此查询?我尝试了子查询,联接等,但无济于事。

3 个答案:

答案 0 :(得分:2)

我认为where中的相关子查询是一种简单的解决方案:

select t.*
from t
where t.col2 = (select max(t2.col2) from t t2 where t2.col1 = t.col1);

这通常具有非常好的性能特征。更传统的解决方案使用row_number(

select t.*
from (select t.*,
             row_number() over (partition by col1 order by col2 desc) as seqnum
      from t
     ) t
where seqnum = 1;

如果您有单独的col1值表,那么apply也可以具有良好的性能:

select t.*
from table_col1 c1 cross apply
     (select top (1) t.*
      from t 
      where t.col1 = c1.col1
      order by t.col2 desc
     ) t;

答案 1 :(得分:0)

您可以尝试:

SELECT a.c1, a.c2, a.c3 
FROM
MyTable a
INNER JOIN
(SELECT c1, MAX(c2) as 'max_c2' FROM MyTable GROUP BY c1) b
ON
a.c1 = b.c1
AND
a.c2 = b.max_c2

答案 2 :(得分:0)

您可以利用OVER()DECLARE @MyTable TABLE(c1 INT, c2 INT, c3 INT) INSERT INTO @MyTable VALUES (1, 32 , 12), (1, 27 , 15), (1, 12 , 21), (2, 23 , 33), (2, 36 , 49), (3, 48 , 17), (3, 21 , 50), (3, 7 , 25) SELECT * FROM ( SELECT c1 , MAX(c2) OVER(PARTITION BY c1) c2 , CASE WHEN c2 = MAX(c2) OVER(PARTITION BY c1) THEN c3 ELSE NULL END c3 FROM @MyTable ) D WHERE c3 IS NOT NULL 子句。

{{1}}