Как написать LINQ.Skip(1000). Захватить (100) в чистом SQL?
Что такое SQL-эквивалент метода .Skip()
в LINQ?
Например: я хотел бы выбрать строки 1000-1100 из конкретной таблицы базы данных.
Возможно ли это с помощью только SQL? Или мне нужно выбрать всю таблицу, а затем найти строки в памяти? В идеале я хотел бы избежать этого, если это возможно, поскольку таблица может быть довольно большой.
Ответы
Ответ 1
В 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
SQL Server 2012 и выше добавили этот синтаксис:
SELECT *
FROM Sales.SalesOrderHeader
ORDER BY OrderDate
OFFSET (@Skip) ROWS FETCH NEXT (@Take) ROWS ONLY
Ответ 3
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 строк, прежде чем запускать для возврата результатов. Слишком часто разработчики забывают об этом и просто бросают контроль над страницами на стол с пятью тысячами строк и задаются вопросом, почему первая страница возвращается намного быстрее, чем последняя...
Тем не менее, используя ROW_NUMBER(), вероятно, лучший баланс между простотой использования и хорошей производительностью, если вы убедитесь, что избегаете сортировки (условие ORDER BY может быть удовлетворено индексом).
Ответ 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
Сделайте это:
Запустите .Skip(1000). Загрузите (100) в LINQ to SQL datacontext и посмотрите на вывод SQL. Он будет генерировать SQL-инструкцию для вас, которая делает то, что вы описываете.
Он не будет таким элегантным, но он выполнит свою работу.
Ответ 6
Нет, но вы можете эмулировать предложение MySQL LIMIT (ссылка) для достижения того же результата.
Ответ 7
Я использую что-то вроде этого, чтобы выбрать первые 100, пропускающие первую 1000.
SELECT TOP(100) *
FROM MY_TABLE
WHERE ID not in (SELECT TOP(1000) ID From My_TABLE);
Вам нужно использовать одно и то же предложение where, если вы хотите фильтровать больше результатов:
SELECT TOP(100) *
FROM MY_TABLE
WHERE WHERE Status = 'P' AND
ID not in (SELECT TOP(1000) ID From My_TABLE WHERE Status = 'P');