如何在表的一个字段中按最小值分组,保留同一行中的所有值?
Posted
技术标签:
【中文标题】如何在表的一个字段中按最小值分组,保留同一行中的所有值?【英文标题】:How do I group by min value in one field of table, keeping all the values from that same row? 【发布时间】:2010-01-30 11:05:33 【问题描述】:我有一张这样的桌子:
Field1 | Field2 | Field3
1 | 1 | 22
1 | 2 | 10
2 | 5 | 40
2 | 2 | 55
我想按 Field1 分组,然后从具有最小 Field2 的行的其余部分取值,例如:
Field1 | Field2 | Field3
1 | 1 | 22
2 | 2 | 55
请注意,这与选择每行的最小值不同,这将给出:
Field1 | Field2 | Field3
1 | 1 | 10
2 | 2 | 40
我的数据将是一个毫无意义的结果。
有人对此有通用(即多数据库)解决方案吗?我确定这一定是一个已解决的问题!
我真的可以使用同时适用于 sqlite 和 ms-access 的解决方案,而 sql server 将是一个奖励。
【问题讨论】:
【参考方案1】:您必须使用子查询来执行此操作。
Select * from
yourtable t
inner join
( Select field1, min(field2) as minField2
from yourtable
group by field1
) xx
on t.field1 = xx.field1 and t.field2 = xx.minfield2
现在,如果您有多个行的最小 field2 值,那么您将有欺骗......如果您不想要那个(即您希望 field3 的最小值对应于 field2 的每个最小值)情况下,您需要另一个子查询:
Select outert.field1, outert.field2, outert.field3
from yourtable outert
inner join
(
Select t.field1, xx.minfield2, min(field3) as minfield3 from
yourtable t
inner join
( Select field1, min(field2) as minField2
from yourtable
group by field1
) xx
on t.field1 = xx.field1 and t.field2 = xx.minfield2
group by t.field1, xx.minfield2
) outerx
on outerx.field1 = outert.field1
and outerx.field2 = outert.minfield2
and outerx.field3 = outert.minfield3
【讨论】:
对此有一个警告,如果xx.field1
和xx.minfield2
可以匹配yourtable
中的多行,例如如果field1 不是键值,这可能会产生意想不到的结果,即连接表中每个 field1 出现多行。如果field1
和minfield2
只能可靠地生成一行,那么这很有效。谢谢:)【参考方案2】:
如您所见,有一个解决方案只使用标准 SQL,但它又长又复杂。
请注意,也可以写“Hello, world!”可以在三种不同的编程语言中正常工作的程序。但是,这样做通常不会为您的程序增加任何价值。只需编写 3 次程序,根据每种语言的特定语法量身定制,就容易多了。
我认为对于 SQL,最好忘记尝试找到适用于所有 RDBMS 的解决方案,并使用特定的供应商扩展和惯用语来简化此类查询。例如在 MS SQL Server 中,你可以这样做:
SELECT Field1, Field2, Field3
FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY field1 ORDER BY field2) AS rn
FROM table1
) AS T1
WHERE rn = 1
不管怎样,你已经有了一个通用的解决方案,所以我只是想我会提供这个替代观点。
【讨论】:
我知道我正在用 sql 为自己的背部做一根棒子,但是一旦我写完它就可以在我当前项目的几个不同地方使用它。 另外,我不想将自己绑定到访问特定的 SQL(这是数据当前所在的位置),因为我试图说服将数据移动到 sqlite 或 SQL 的权力服务器。以上是关于如何在表的一个字段中按最小值分组,保留同一行中的所有值?的主要内容,如果未能解决你的问题,请参考以下文章