微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何按一列分组,并在T / SQL中检索另一列的最小值的行?

所以我知道这是一个非常愚蠢的问题,但是(正如相当长的标题所说),我想知道如下:

我有这样的表:

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中的值进行分组,因为它不知道如何在它们之间进行选择.

原文地址:https://www.jb51.cc/mssql/81328.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐