拥有某一列的按组最大值的行如何杀死重复项……

问题描述

| 我之前曾问过类似的问题,但是这种相似性是肤浅的,问题出在更深的地方…… 因此,请考虑以下MS sql Server 2008表:
  ID  |   X   |   Y
------+-------+-------
   1  |   1   |   1
   2  |   1   |   2
   3  |   1   |   2
   4  |   1   |   3
   5  |   1   |   3
   6  |   2   |   4
   7  |   2   |   5
   8  |   2   |   5
   9  |   2   |   5
  10  |   3   |   1
  11  |   3   |   10
  12  |   3   |   10
我需要接收以下结果之一(这到底是什么并不重要):
  ID  |   X   |   Y
------+-------+-------
   4  |   1   |   3
   7  |   2   |   5
  11  |   3   |   10
要么
  ID  |   X   |   Y
------+-------+-------
!! 5  |   1   |   3
   7  |   2   |   5
  11  |   3   |   10
要么
.....
要么
  ID  |   X   |   Y
------+-------+-------
   5  |   1   |   3
   9  |   2   |   5
  12  |   3   |   10
我需要 X分组表 选择最大Y 选择最大Y的ID 结果也应按X分组 不应出现以下结果:
  ID  |   X   |   Y
------+-------+-------
   4  |   1   |   3
   5  |   1   |   3
   7  |   2   |   5
   8  |   2   |   5
   9  |   2   |   5
  11  |   3   |   10
  12  |   3   |   10
    

解决方法

        
DECLARE @Data TABLE (ID INTEGER,X INTEGER,Y INTEGER)
INSERT @Data VALUES (1,1,1),(2,2),(3,(4,3),(5,(6,2,4),(7,5),(8,(9,(10,3,(11,10),(12,10)

;WITH CTE AS
(
SELECT ID,X,Y,ROW_NUMBER() OVER(PARTITION BY X ORDER BY Y DESC,ID ASC) AS RowNo
FROM @Data
)

SELECT ID,Y FROM CTE WHERE RowNo = 1
因此,使用ROW_NUMBER()为每一行分配一个递增的数字,对于每个新的X值,该数字将重置为1。对于X值相同的行,行号由Y降序和ID升序递增分配-因此,对于特定的X值,行号1将分配给具有最高Y值和最低ID值的行。然后,我们添加一个限制,以仅返回RowNo为1的那些。     ,        这将为x,y的每个重复组合带来第一行
SELECT t1.*
FROM tablename t1
INNER JOIN
(SELECT MIN(id) id FROM tablename GROUP BY X,Y HAVING COUNT(*)>1)
 t2 ON t1.id = t2.id
测试代码得到以下结果:
ID  X   Y   
2   1   2   
4   1   3   
7   2   5   
11  3   10  
    ,        对于此类任务,还有一个更优雅的解决方案:
DECLARE @Data TABLE (ID INTEGER,Y INTEGER);

INSERT @Data VALUES (1,1);
INSERT @Data VALUES (2,2);
INSERT @Data VALUES (3,2);
INSERT @Data VALUES (4,3);
INSERT @Data VALUES (5,3);
INSERT @Data VALUES (6,4);
INSERT @Data VALUES (7,5);
INSERT @Data VALUES (8,5);
INSERT @Data VALUES (9,5);
INSERT @Data VALUES (10,1);
INSERT @Data VALUES (11,10);
INSERT @Data VALUES (12,10);

SELECT TOP 1 WITH TIES 
    ID,Y
FROM @Data
ORDER BY ROW_NUMBER() OVER(PARTITION BY X ORDER BY Y DESC,ID ASC);