聚合查询中的非分组列

问题描述 投票:0回答:3

说我有一个有三列的表: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.

我该如何修复此查询?我尝试过子查询,连接等无济于事。

sql sql-server
3个回答
0
投票

你可以利用CASEOVER()条款。

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 

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;

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
© www.soinside.com 2019 - 2024. All rights reserved.