如何使用group by将多个列组合在一起并选择其余列上的前1个?

时间:2014-01-08 11:22:46

标签: sql sql-server select group-by min

我在MS Sql Server中有一个表

AA   BB   CC   DD
---- ---- ---- ----
a1   b1   c1   d1
a1   b1   c2   d2
a1   b1   c3   d3
a2   b1   c4   d4
a1   b2   c5   d5

我想要的查询是这样的:

如果多行具有相同的AA和相同的BB,则应仅显示其中一行,并且该行应具有最少的CC。

假设c1< c2< c3,然后我想要的表是

AA   BB   CC   DD
---- ---- ---- ----
a1   b1   c1   d1
a1   b2   c5   d5
a2   b1   c4   d4

如何撰写此查询?

2 个答案:

答案 0 :(得分:1)

从SQL Server 2008开始,您可以使用ROW_NUMBER()函数:

SELECT aa,bb,cc,dd
      ,ROW_NUMBER() OVER (PARTITION BY aa,bb ORDER BY cc ASC) r
FROM table;

AA   BB   CC   DD   r
---- ---- ---- ---- --------------------
a1   b1   c1   d1   1
a1   b1   c2   d2   2
a1   b1   c3   d3   3
a1   b2   c5   d5   1
a2   b1   c4   d4   1

使用此作为子选择来获得结果:

SELECT aa,bb,cc,dd FROM (
  SELECT aa,bb,cc,dd
         ,ROW_NUMBER() OVER (PARTITION BY aa,bb ORDER BY cc ASC) r
  FROM table) q1
WHERE r = 1;

如果多行共享相同的最小值,则数据库选择一行。如果你想要全部返回它们,用RANK()替换ROW_NUMBER()函数。

SQL Fiddle

答案 1 :(得分:0)

试试这个:

SELECT A.AA, A.BB, A.CC, A.DD 
FROM tableA A 
INNER JOIN (SELECT AA, BB, MIN(CC) AS CC 
            FROM tableA GROUP BY AA, BB
           ) B ON A.AA = B.AA AND A.BB = B.BB AND A.CC = B.CC 

SELECT AA, BB, MIN(CC) AS CC, MIN(DD) AS DD
FROM tableA 
GROUP BY AA, BB