我之前曾问过类似的问题,但这种相似性是肤浅的,问题在于更深层次......
请考虑以下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
答案 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);