我们有一个包含四列的数据结构:
ContractoreName, ProjectCode, InvoiceID, OrderID
我们希望按ContractoreName
和ProjectCode
列对数据进行分组,然后使用InvoiceID
为每个组获取行的MAX(OrderID)
。
答案 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
并获得相同的效果。