2012-03-20 40 views
4

我的表看起来像:SQL服务器:最大-N-每组扩展

A  B  C  D 
1  1  1  1 
1  1  3  2 
1  1  0  4 
1  1  2  1  
1  2  1  0 
1  2  0  2 
1  2  4  5 
2  1  5  3 

我的目标是,对于每对A和B的,输出在对应于MIN d值(C )和D中对应于MAX(C)的值。输出应该

A B D at MIN(C) D at MAX(C) 
1 1 4    2 
1 2 2    5 
2 1 3    3 

我知道,提取MIN(C)和MAX(C)我只是做:

SELECT A, B, MIN(C) as "minC", MAX(C) as "maxC" 
FROM Table 
GROUP BY A, B 
ORDER BY A, B 

我的问题是:我怎么把列d凑凑热闹?如果我将它包含在SELECT和GROUP BY子句中,它将为每个D生成MIN(C)和MAX(C),这不是我想要的。而且,我甚至不需要输出MIN(C)和MAX(C)。 D是我所追求的。

SQL Select only rows with Max Value on a Column中提供的基本概述似乎无法处理这种情况。

在此先感谢!

回答

4

你的查询可以是这个样子:

;with C as 
(
    select A, B, C, D, 
     row_number() over(partition by A, B order by C asc) as rn1, 
     row_number() over(partition by A, B order by C desc) as rn2 
    from YourTable 
) 
select C1.A, C1.B, C1.D as "D at MIN(C)", C2.D as "D at MAX(C)" 
from C as C1 
    inner join C as C2 
    on C1.A = C2.A and 
     C1.B = C2.B 
where C1.rn1 = 1 and 
     C2.rn2 = 1 

,第一部分是common table expression (CTE)封装,可以在后面的主被重用查询查询。它使用row_number()来枚举每个分区内的行。 rn1订购C asc所以rn1 = 1最小值为Crn2订购C desc并且这意味着rn2 = 1最大值为C。主要查询是使用CTE两次加入AB列。 Where子句确保我们只获得rn1rn21的行。

这是一个工作示例,它使用表变量@T而不是表格。

declare @T table 
(
    A int, 
    B int, 
    C int, 
    D int 
) 

insert into @T values 
(1,  1,  1,  1), 
(1,  1,  3,  2), 
(1,  1,  0,  4), 
(1,  1,  2,  1), 
(1,  2,  1,  0), 
(1,  2,  0,  2), 
(1,  2,  4,  5), 
(2,  1,  5,  3) 

;with C as 
(
    select A, B, C, D, 
     row_number() over(partition by A, B order by C asc) as rn1, 
     row_number() over(partition by A, B order by C desc) as rn2 
    from @T 
) 
select C1.A, C1.B, C1.D as "D at MIN(C)", C2.D as "D at MAX(C)" 
from C as C1 
    inner join C as C2 
    on C1.A = C2.A and 
     C1.B = C2.B 
where C1.rn1 = 1 and 
     C2.rn2 = 1 
+0

我是新来的SQL-有没有办法做到这一点,而无需将数据插入到新表中?可以将“with”命令应用于已经存在的表格吗?我使用的表格非常大(我相信不可变)。谢谢你的帮助! – ddp26 2012-03-20 15:43:12

+0

@ ddp26 - 我已经更新了答案。我希望现在会更清楚。 – 2012-03-20 16:05:46

0

像这样的东西可能会奏效:

SELECT A, B, MIN(C) as "minC", MAX(C) as "maxC", 
(SELECT TOP 1 D FROM Table [table2] WHERE table1.A = table2.A AND table1.B = table2.B AND MIN(table1.C) = table2.C) As [D] 
FROM Table [table1] 
GROUP BY A, B 
ORDER BY A, B 
+0

[table1]和[table2]在这里指的是什么?我只有输入表。 – ddp26 2012-03-20 15:38:36

+0

这两个引用您的表“表”。将Table2视为一个连接,它可以选择A,B,MIN(C)对的所有d值。 – zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz 2012-03-20 15:59:47