行保持某一列的组最大值(如何杀死重复...)

时间:2011-06-23 10:01:03

标签: sql sql-server sql-server-2008

我之前曾问过类似的问题,但这种相似性是肤浅的,问题在于更深层次......

请考虑以下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

我需要

  1. X分组表

  2. 选择最大Y

  3. 选择最大Y的ID

  4. 结果也应按X

  5. 分组

    不应该有这样的结果:

      ID  |   X   |   Y
    ------+-------+-------
       4  |   1   |   3
       5  |   1   |   3
       7  |   2   |   5
       8  |   2   |   5
       9  |   2   |   5
      11  |   3   |   10
      12  |   3   |   10
    

3 个答案:

答案 0 :(得分:2)

DECLARE @Data TABLE (ID INTEGER, X INTEGER, Y INTEGER)
INSERT @Data VALUES (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)

;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, X, Y FROM CTE WHERE RowNo = 1

因此,使用ROW_NUMBER()为每一行分配一个增量数,每个新X值重置为1。对于具有相同X值的行,行号由Y DESCENDING和ID ASCENDING按递增顺序分配 - 因此对于特定X值,行号1将分配给具有最高Y值和最低ID值的行号。然后我们添加一个限制,只返回RowNo为1的那些。

答案 1 :(得分:2)

这将为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  

答案 2 :(得分:1)

对于这类任务,还有一个更优雅的解决方案:

DECLARE @Data TABLE (ID INTEGER, X INTEGER, Y INTEGER);

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

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