Как написать LINQ's. Skip (1000).Взять(100) в чистом SQL?


что такое SQL эквивалент .Skip() метод в LINQ?

например: я хотел бы выбрать строки 1000-1100 из конкретной таблицы базы данных.

это возможно только с SQL? Или мне нужно выбрать всю таблицу, а затем найти строки в памяти? В идеале я хотел бы избежать этого, если это возможно, так как таблица может быть довольно большой.

6 90

6 ответов:

в 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

SQL Server 2012 и выше добавили этот синтаксис:

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

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;

это работает, но нужно изготовить row_number из ORDER BY мая результат в вашем запросе сортируется на стороне сервера и вызвать проблемы с производительностью. Даже если индекс может удовлетворять требованию ORDER BY, запрос все равно должен считать 1000 строк до начала возврата результатов. Слишком часто разработчики забывают об этом и просто бросают контроль над разбиением на страницы на 5 миллионов строки таблицы и интересно, почему первая страница возвращается намного быстрее, чем последняя...

тем не менее, использование ROW_NUMBER (), вероятно, является лучшим балансом между простотой использования и хорошей производительностью, если вы убедитесь, что вы избегаете сортировки (порядок по условию может быть удовлетворен индексом).

этого:

выполнить .Пропустить(1000).Возьмите(100) на LINQ to SQL datacontext и посмотрите на вывод SQL. Он будет генерировать SQL-оператор для вас, который делает то, что вы описываете.

Это будет не так элегантно, но он получает работу.

попробуй это:

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

нет, но ты могла!--1-- > эмулировать предельное предложение MySQL (ссылка переполнения стека) для достижения того же результата.