T-Sql中的“Over”子句到底有什么作用?

时间:2009-02-15 22:55:19

标签: sql asp.net-mvc over-clause

我开始搞乱ASP.NET MVC并遇到了想要做一些基本的Paging的问题。所以我使用这个简单的Linq语句(使用Northwind数据库)获取特定页面的10个项目:

var q = (from p in db.Orders
                     orderby p.OrderDate descending
                     select p).Skip(currentPage * pageAmount).Take(pageAmount);

它运行良好,但是当我调试时,我很好奇Linq到Sql生成的实际SQL是什么。这是输出:

SELECT [t1].[OrderID], [t1].[CustomerID], [t1].[EmployeeID], [t1].[OrderDate], [t1].[RequiredDate], [t1].[ShippedDate], [t1].[ShipVia], [t1].[Freight], [t1].[ShipName], [t1].[ShipAddress], [t1].[ShipCity], [t1].[ShipRegion], [t1].[ShipPostalCode], [t1].[ShipCountry]
FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY [t0].[OrderDate] DESC) AS [ROW_NUMBER], [t0].[OrderID], [t0].[CustomerID], [t0].[EmployeeID], [t0].[OrderDate], [t0].[RequiredDate], [t0].[ShippedDate], [t0].[ShipVia], [t0].[Freight], [t0].[ShipName], [t0].[ShipAddress], [t0].[ShipCity], [t0].[ShipRegion], [t0].[ShipPostalCode], [t0].[ShipCountry]
    FROM [dbo].[Orders] AS [t0]
    ) AS [t1]
WHERE [t1].[ROW_NUMBER] BETWEEN @p0 + 1 AND @p0 + @p1
ORDER BY [t1].[ROW_NUMBER]

现在我根本不是SQL专家,这就是我从未见过“OVER”条款的原因。我只是从高级别开始对这究竟是什么以及何时使用它感到好奇?

3 个答案:

答案 0 :(得分:3)

ROW_NUMBER() OVER

  

返回行的序号   在结果集的分区内,   在第一行从1开始   每个分区。

在您的示例中,结果集按降序OrderDate排序,然后ROW_NUMBER函数应用于它。返回的结果集只会在ROW_NUMBER is BETWEEN (@p0 + 1) and (@p0 + @p1)

的位置

正如DOK所说,OVER子句不是单独使用,而是与聚合和排名窗口函数结合使用。

来自MSDN -

  

OVER子句(Transact-SQL)

     

确定分区和   在之前排序行集   应用相关的窗口函数。

答案 1 :(得分:1)

它告诉ROW_NUMBER函数如何根据括号内的表达式为每一行分配一个数字。但是,实际上不会根据子查询中的这个数字对行进行排序。这就是外部查询中的排序。

答案 2 :(得分:1)

OVER不是单独使用的。它与RANK,DENSE RANK,NTILE和ROW NUMBER一起使用。在这种情况下,它与ROW_NUMBER一起用于仅检索当时显示所需的记录,在这种情况下是该页面的10个项目。