因此,我知道这是一个非常愚蠢的问题,但是(正如冗长的标题所言),我想知道以下操作:
我有一个这样的表:
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不会汇总。
我究竟做错了什么?
这是我模拟你的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”
null
根据您的用例,重复Bar的重复值可能是有效的-如果您想在Borg中找到Bar最小的所有值,那么同时获得两个结果似乎是可行的方法。
如果您需要捕获NULLs要聚合的字段(在这种情况下为MIN),则可以coalesce使用具有可接受的高(或低)值的NULL(这是hack):
NULLs
coalesce
... 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值,因为它不知道如何在它们之间进行选择。
Foo