如何在纯SQL中编写LINQ的.Skip(1000).Take(100)?

时间:2009-11-16 20:56:39

标签: .net sql sql-server

LINQ中.Skip()方法的SQL等价物是什么?

例如:我想从特定的数据库表中选择行1000-1100。

这只能用SQL吗?或者我是否需要选择整个表,然后在内存中查找行?如果可能的话,我最好避免这种情况,因为表格可能非常大。

6 个答案:

答案 0 :(得分:134)

SQL Server 2012及更高版本添加了以下语法:

SELECT *
FROM Sales.SalesOrderHeader 
ORDER BY OrderDate
OFFSET (@Skip) ROWS FETCH NEXT (@Take) ROWS ONLY

答案 1 :(得分:77)

在SQL Server 2005及更高版本中,您可以使用ROW_NUMBER函数。例如

USE AdventureWorks;
GO
WITH OrderedOrders AS
(
    SELECT SalesOrderID, OrderDate,
    ROW_NUMBER() OVER (ORDER BY OrderDate) AS 'RowNumber'
    FROM Sales.SalesOrderHeader 
) 
SELECT * 
FROM OrderedOrders 
WHERE RowNumber BETWEEN 51 AND 60; --BETWEEN is inclusive

答案 2 :(得分:22)

LINQ to SQL通过使用ROW_NUMBER窗口函数来完成此操作:

  SELECT a,b,c FROM 
   (SELECT a,b,c, ROW_NUMBER() OVER (ORDER BY ...) as row_number
    FROM Table) t0
   WHERE to.row_number BETWEEN 1000 and 1100;

这样可行,但是需要从ORDER BY 生成row_number可能导致您的查询在服务器端进行排序并导致性能问题。即使索引可以满足ORDER BY要求,查询仍然必须在开始返回结果之前计数1000行。开发人员常常忘记这一点,只是在一个5密耳的行表上抛出一个分页控件,并想知道为什么第一页的返回速度比最后一页快得多......

尽管如此,使用ROW_NUMBER()可能是易用性和良好性能之间的最佳平衡,前提是确保避免排序(索引可以满足ORDER BY条件)。

答案 3 :(得分:4)

这样做:

运行.Skip(1000)。在LINQ to SQL datacontext上获取(100)并查看SQL输出。它将为您生成一个SQL语句,用于执行您所描述的内容。

它不会那么优雅,但它可以完成工作。

答案 4 :(得分:4)

试试这个:

select * from [Table-Name] order by [Column-Name] 
offset [Skip-Count] rows
FETCH NEXT [Take-Count] rows only

示例:

select * from Personals order by Id
offset 10 rows            --------->Skip 10
FETCH NEXT 15 rows only   --------->Take 15

答案 5 :(得分:2)

不,但您可以emulate MySQL's LIMIT clause(Stack Overflow链接)来获得相同的结果。