使用两个分组获取具有最大值的行的id

时间:2018-04-21 12:01:07

标签: sql-server tsql group-by

我们有一个包含四列的数据结构:

ContractoreName, ProjectCode, InvoiceID, OrderID

我们希望按ContractoreNameProjectCode列对数据进行分组,然后使用InvoiceID为每个组获取行的MAX(OrderID)

2 个答案:

答案 0 :(得分:2)

您可以使用SELECT ContractorName, ProjectName, OrderId, InvoiceId FROM (SELECT *, ROW_NUMBER() OVER(PARTITION BY ContractorName, ProjectName ORDER BY OrderId DESC) AS rn FROM tab ) AS sub WHERE rn = 1;

{{1}}

答案 1 :(得分:2)

ROW_NUMBER()就是我所说的规范解决方案。在许多情况下,老式解决方案具有更好的性能:

select t.*
from t
where t.orderid = (select max(t2.orderid)
                   from t t2
                   where t2.contractorname = t.contractorname and
                         t2.projectname = t.projectname
                  );

如果(contractorname, projectname, orderid)上有索引,则尤其如此。

为什么这会更快?基本上,SQL Server可以扫描表在索引中执行查找。查找非常快,因为索引是为它设计的,所以扫描只比全表扫描快一点。

使用row_number()时,SQL Server必须扫描表以计算行号(并且可以使用索引,因此它可能很快)。但是它必须返回到表中来获取列并应用where子句。因此,即使它使用索引,它也会做更多工作。

编辑:

我还应该指出,这可以在没有子查询的情况下完成:

select distinct contractorname, projectname,
       max(orderid) over (partition by contractorname, projectname) as lastest_order,
       first_value(invoiceid) partition by (order by contractorname, projectname order by orderid desc) as lastest_invoice
from t;

不幸的是,SQL Server不提供first_value()作为聚合函数,但您可以使用select distinct并获得相同的效果。