说我有一个包含三列的表:c1
,c2
和c3
。我想在每个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.
如何解决此查询?我尝试了子查询,联接等,但无济于事。
答案 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}}