У мене є цей запит у MySQL:
select * from table1 LIMIT 10,20
Як я можу це зробити за допомогою SQL Server?
У мене є цей запит у MySQL:
select * from table1 LIMIT 10,20
Як я можу це зробити за допомогою SQL Server?
Відповіді:
Починаючи SQL SERVER 2005, ви можете це зробити ...
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 10 AND 20;
або щось подібне для 2000 та нижче версій ...
SELECT TOP 10 * FROM (SELECT TOP 20 FROM Table ORDER BY Id) ORDER BY Id DESC
Клункі, але це спрацює.
SELECT TOP 10 * FROM table WHERE id NOT IN (SELECT TOP 10 id FROM table ORDER BY id) FROM table ORDER BY id
Відмова MSSQL від пункту LIMIT є злочинним, IMO. Вам не слід було б робити подібні хитрі рішення.
Починаючи з SQL SERVER 2012, ви можете використовувати пункт OFFSET FETCH:
USE AdventureWorks;
GO
SELECT SalesOrderID, OrderDate
FROM Sales.SalesOrderHeader
ORDER BY SalesOrderID
OFFSET 10 ROWS
FETCH NEXT 10 ROWS ONLY;
GO
http://msdn.microsoft.com/en-us/library/ms188385(v=sql.110).aspx
Це може не працювати правильно, коли замовлення не є унікальним.
Якщо запит буде змінено на ORDER BY OrderDate, повернутий набір результатів не є таким, як очікувалося.
Це майже дублікат запитання, яке я задав у жовтні: Емуляція пункту MySQL LIMIT в Microsoft SQL Server 2000
Якщо ви використовуєте Microsoft SQL Server 2000, хорошого рішення немає. Більшість людей доводиться вдаватися до фіксації результату запиту у тимчасовій таблиці з IDENTITY
первинним ключем. Потім запитуйте стовпчик первинного ключа, використовуючи BETWEEN
умову.
Якщо ви використовуєте Microsoft SQL Server 2005 або новішої версії, у вас є ROW_NUMBER()
функція, тому ви можете отримати той же результат, але уникати тимчасової таблиці.
SELECT t1.*
FROM (
SELECT ROW_NUMBER OVER(ORDER BY id) AS row, t1.*
FROM ( ...original SQL query... ) t1
) t2
WHERE t2.row BETWEEN @offset+1 AND @offset+@count;
Ви також можете написати це як загальне вираз таблиці , як показано в @Leon Tayson в відповідь .
Ось як я обмежую результати в MS SQL Server 2012:
SELECT *
FROM table1
ORDER BY columnName
OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY
ПРИМІТКА: OFFSET
можна використовувати лише з та в тандемі до ORDER BY
.
Пояснити рядок коду OFFSET xx ROWS FETCH NEXT yy ROW ONLY
Номер xx
запису / рядка, з якого потрібно починати витягування, в таблиці, тобто: Якщо в таблиці 1 є 40 записів, код вище почне витягуватися з рядка 10.
Це yy
кількість записів / рядків, які потрібно витягнути з таблиці.
Щоб побудувати на попередньому прикладі: Якщо таблиця 1 містить 40 записів, і ви почали витягувати з рядка 10 і захопити наступний набір 10 ( yy
). Це означає, що наведений вище код буде витягувати записи з таблиці 1, починаючи з рядка 10 і закінчуючи в 20. Таким чином, витягуючи рядки 10 - 20.
Перевірте посилання для отримання додаткової інформації на OFFSET
SELECT *
FROM (
SELECT TOP 20
t.*, ROW_NUMBER() OVER (ORDER BY field1) AS rn
FROM table1 t
ORDER BY
field1
) t
WHERE rn > 10
Синтаксично запит MySQL LIMIT виглядає приблизно так:
SELECT * FROM table LIMIT OFFSET, ROW_COUNT
Це можна перекласти на Microsoft SQL Server, як
SELECT * FROM
(
SELECT TOP #{OFFSET+ROW_COUNT} *, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rnum
FROM table
) a
WHERE rnum > OFFSET
Тепер ваш запит select * from table1 LIMIT 10,20
буде таким:
SELECT * FROM
(
SELECT TOP 30 *, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rnum
FROM table1
) a
WHERE rnum > 10
Це одна з причин, що я намагаюся уникати використання MS Server ... але все одно. Іноді у вас просто немає можливості (так! І мені доводиться використовувати застарілу версію !!).
Моя пропозиція - створити віртуальну таблицю:
Від:
SELECT * FROM table
До:
CREATE VIEW v_table AS
SELECT ROW_NUMBER() OVER (ORDER BY table_key) AS row,* FROM table
Тоді просто запитай:
SELECT * FROM v_table WHERE row BETWEEN 10 AND 20
Якщо поля додані чи видалені, "рядок" оновлюється автоматично.
Основна проблема цього варіанту полягає в тому, що ЗАМОВЛЕННЯ ВИМОГА. Тож якщо ви хочете іншого порядку, вам доведеться створити інший вигляд.
ОНОВЛЕННЯ
З цим підходом є ще одна проблема: якщо ви спробуєте відфільтрувати свої дані, він не працюватиме, як очікувалося. Наприклад, якщо ви робите:
SELECT * FROM v_table WHERE field = 'test' AND row BETWEEN 10 AND 20
ЧИМО обмежується тими даними, які знаходяться в рядках між 10 і 20 (замість того, щоб шукати весь набір даних і обмежувати вихід).
SELECT
*
FROM
(
SELECT
top 20 -- ($a) number of records to show
*
FROM
(
SELECT
top 29 -- ($b) last record position
*
FROM
table -- replace this for table name (i.e. "Customer")
ORDER BY
2 ASC
) AS tbl1
ORDER BY
2 DESC
) AS tbl2
ORDER BY
2 ASC;
-- Examples:
-- Show 5 records from position 5:
-- $a = 5;
-- $b = (5 + 5) - 1
-- $b = 9;
-- Show 10 records from position 4:
-- $a = 10;
-- $b = (10 + 4) - 1
-- $b = 13;
-- To calculate $b:
-- $b = ($a + position) - 1
-- For the present exercise we need to:
-- Show 20 records from position 10:
-- $a = 20;
-- $b = (20 + 10) - 1
-- $b = 29;
Потрібно спробувати. У нижченаведеному запиті ви можете побачити групування, упорядкування, пропуск рядків та обмеження рядків.
select emp_no , sum(salary_amount) from emp_salary
Group by emp_no
ORDER BY emp_no
OFFSET 5 ROWS -- Skip first 5
FETCH NEXT 10 ROWS ONLY; -- limit to retrieve next 10 row after skiping rows
SELECT TOP 10 * FROM table;
Це те саме, що
SELECT * FROM table LIMIT 0,10;
Ось стаття про впровадження Limit в MsSQL Приємне прочитання, особливо коментарі.
У SQL немає ключового слова LIMIT. Якщо вам потрібна лише обмежена кількість рядків, ви повинні використовувати ключове слово TOP, яке є подібним до LIMIT.
Якщо ваш ідентифікатор є унікальним типом ідентифікатора або ваш ідентифікатор в таблиці не відсортований, ви повинні зробити так, як описано нижче.
select * from
(select ROW_NUMBER() OVER (ORDER BY (select 0)) AS RowNumber,* from table1) a
where a.RowNumber between 2 and 5
Код буде
виберіть * від межі 2,5
краще використовувати це в MSSQLExpress 2017.
SELECT * FROM
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) as [Count], * FROM table1
) as a
WHERE [Count] BETWEEN 10 and 20;
--Задання стовпця [Порахуйте] та призначення кожному рядку унікального підрахунку, не замовляючи щось, потім знову виберіть, де ви можете вказати свої межі .. :)
Один із можливих способів отримати результат, як показано нижче, сподіваюся, що це допоможе.
declare @start int
declare @end int
SET @start = '5000'; -- 0 , 5000 ,
SET @end = '10000'; -- 5001, 10001
SELECT * FROM (
SELECT TABLE_NAME,TABLE_TYPE, ROW_NUMBER() OVER (ORDER BY TABLE_NAME) as row FROM information_schema.tables
) a WHERE a.row > @start and a.row <= @end
Якщо я правильно пам’ятаю (минуло деякий час, коли я зайнявся програмою SQL Server), можливо, ви зможете використовувати щось подібне: (2005 р. І вище)
SELECT
*
,ROW_NUMBER() OVER(ORDER BY SomeFields) AS [RowNum]
FROM SomeTable
WHERE RowNum BETWEEN 10 AND 20
WHERE
на псевдонім, визначений у тому самому рівні SELECT
.