所以我知道这是一个非常愚蠢的问题,但是(正如相当长的标题所说),我想知道如下:
我有这样的表:
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,Bar和Blagh未聚合.
我究竟做错了什么?
解决方法
This几乎是完全一样的问题,但它有一些答案!
这是我嘲笑你的桌子:
declare @Borg table ( ID int,Foo int,Bar int,Blagh int ) insert into @Borg values (1,10,20,30) insert into @Borg values (2,5,1) insert into @Borg values (3,50,70) insert into @Borg values (4,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为null的任何foo值”
根据您的使用情况,重复条形码的重复值可能是有效的 – 如果您想在Borg中找到所有值,其中Bar最小,那么这两个结果似乎都是要走的.
如果您需要在要聚合的字段中捕获NULL(在本例中为MIN),则可以以可接受的高(或低)值(这是一个黑客)来合并NULL.
... 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
后者不会使用相同的Foo值对@Borg中的值进行分组,因为它不知道如何在它们之间进行选择.