问题描述
这是我模拟你的table:
declare @Borg table (
ID int,
Foo int,
Bar int,
Blagh int
)
insert into @Borg values (1,10,20,30)
insert into @Borg values (2,10,5,1)
insert into @Borg values (3,20,50,70)
insert into @Borg values (4,20,75,12)
然后,您可以进行匿名内部联接以获取所需的数据。
select B.* from @Borg B inner join
(
select Foo,
MIN(Bar) MinBar
from @Borg
group by Foo
) FO
on FO.Foo = B.Foo and FO.MinBar = B.Bar
亚当·罗宾逊(Adam
Robinson)有益地指出:“当Bar的最小值重复时,此解决方案有可能返回多行,并消除bar为的foo的任何值null
”
根据您的用例,重复Bar的重复值可能是有效的-如果您想在Borg中找到Bar最小的所有值,那么同时获得两个结果似乎是可行的方法。
如果您需要捕获NULLs
要聚合的字段(在这种情况下为MIN),则可以coalesce
使用具有可接受的高(或低)值的NULL(这是hack):
...
MIN(coalesce(Bar,1000000)) MinBar -- A suitably high value if you want to exclude this row, make it suitably low to include
...
或者,您可以使用UNION,并将所有这些值附加到结果集的底部。
on FO.Foo = B.Foo and FO.MinBar = B.Bar
union select * from @Borg where Bar is NULL
后者不会将@Borg中的值分组为相同的Foo
值,因为它不知道如何在它们之间进行选择。
解决方法
因此,我知道这是一个非常愚蠢的问题,但是(正如冗长的标题所言),我想知道以下操作:
我有一个这样的表:
ID Foo Bar Blagh
----------------
1 10 20 30
2 10 5 1
3 20 50 40
4 20 75 12
我想按Foo分组,然后拉出具有最小Bar的行,即我想要以下内容:
ID Foo Bar Blagh
----------------
2 10 5 1
3 20 50 40
我无法终生制定出正确的SQL来检索此信息。我想要类似的东西:
SELECT ID,Foo,Bar,Blagh
FROM Table
GROUP BY Foo
HAVING(MIN(Bar))
但是,这显然是行不通的,因为这完全是无效的HAVING语法,并且ID,Foo,Bar和Blagh不会汇总。
我究竟做错了什么?