Jak zaimplementować LIMIT w SQL Server?

Mam takie zapytanie z MySQL:

select * from table1 LIMIT 10,20

Jak mogę to zrobić z SQL Server?

Author: Dale K, 2009-03-02

18 answers

Uruchamiając SQL SERVER 2005, możesz to zrobić...

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;

Lub coś w tym stylu dla wersji 2000 i poniżej...

SELECT TOP 10 * FROM (SELECT TOP 20 FROM Table ORDER BY Id) ORDER BY Id DESC
 135
Author: Leon Tayson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-02 20:07:04

Niezgrabne, ale zadziała.

SELECT TOP 10 * FROM table WHERE id NOT IN (SELECT TOP 10 id FROM table ORDER BY id) FROM table ORDER BY id

Pominięcie przez MSSQL klauzuli granicznej jest przestępstwem, IMO. Nie powinieneś tego obejść.

 59
Author: ceejayoz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-02 19:58:12

Począwszy od SQL SERVER 2012, możesz użyć klauzuli 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

Może to nie działać poprawnie, gdy order by nie jest unikalny.

Jeśli zapytanie zostanie zmienione na ORDER BY OrderDate, zwracany zestaw wyników nie będzie zgodny z oczekiwaniami.

 42
Author: user4047259,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-08-06 19:29:41

To prawie duplikat pytania, które zadałem w październiku.: Emulacja klauzuli limitu MySQL w Microsoft SQL Server 2000

Jeśli używasz Microsoft SQL Server 2000, nie ma dobrego rozwiązania. Większość ludzi musi uciekać się do przechwytywania wyniku zapytania w tymczasowej tabeli za pomocą klucza podstawowego IDENTITY. Następnie zapytanie z kolumną klucza głównego, używając warunku BETWEEN.

Jeśli używasz Microsoft SQL Server 2005 lub nowszego, masz funkcję ROW_NUMBER(), dzięki której możesz uzyskaj ten sam wynik, ale unikaj tymczasowej tabeli.

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;

Możesz również zapisać to jako common table expression , Jak pokazano w odpowiedzi @ Leon Tayson .

 18
Author: Bill Karwin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:33:16

Tak ograniczam wyniki w MS SQL Server 2012:

SELECT * 
FROM table1
ORDER BY columnName
  OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY

UWAGA: OFFSET może być używany tylko z lub w tandemie do ORDER BY.

Aby wyjaśnić linię kodu OFFSET xx ROWS FETCH NEXT yy ROW ONLY

xx jest numerem rekordu/wiersza, z którego chcesz zacząć pobierać w tabeli, tzn.: jeśli w tabeli 1 jest 40 rekordów, powyższy kod zacznie pobierać z wiersza 10.

yy jest liczbą rekordów / wierszy, które chcesz pobrać z tabeli.

Do zbudowania na poprzednim przykładzie: If table 1 ma 40 rekordów i zacząłeś ciągnąć z rzędu 10 i chwycić następny zestaw 10 (yy). Oznaczałoby to, że powyższy kod spowoduje pobranie rekordów z tabeli 1, począwszy od wiersza 10, a skończywszy na 20. W ten sposób ciągnąc rzędy 10 - 20.

Sprawdź link, aby uzyskać więcej informacji na temat OFFSET

 18
Author: Jeremy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-28 14:51:30
SELECT  *
FROM    (
        SELECT  TOP 20
                t.*, ROW_NUMBER() OVER (ORDER BY field1) AS rn
        FROM    table1 t
        ORDER BY
                field1
        ) t
WHERE   rn > 10
 12
Author: Quassnoi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-25 07:49:31

Składniowo Zapytanie o limit MySQL jest mniej więcej takie:

SELECT * FROM table LIMIT OFFSET, ROW_COUNT

Można to przetłumaczyć na Microsoft SQL Server jak

SELECT * FROM 
(
    SELECT TOP #{OFFSET+ROW_COUNT} *, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rnum 
    FROM table
) a
WHERE rnum > OFFSET

Teraz Twoje zapytanie select * from table1 LIMIT 10,20 będzie takie:

SELECT * FROM 
(
    SELECT TOP 30 *, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rnum 
    FROM table1
) a
WHERE rnum > 10 
 9
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-06 12:25:17

Jest to jeden z powodów, dla których staram się unikać korzystania z MS Server... ale w każdym razie. Czasami po prostu nie masz opcji (yei! i muszę użyć przestarzałej wersji!!).

Moja propozycja to stworzenie wirtualnej tabeli:

From:

SELECT * FROM table

Do:

CREATE VIEW v_table AS    
    SELECT ROW_NUMBER() OVER (ORDER BY table_key) AS row,* FROM table

Następnie po prostu zapytanie:

SELECT * FROM v_table WHERE row BETWEEN 10 AND 20

Jeśli pola są dodawane lub usuwane, "wiersz" jest aktualizowany automatycznie.

Główny problem z tą opcją polega na tym, że ORDER BY jest naprawione. Więc jeśli chcesz innej kolejności, to muszę stworzyć inny widok.

UPDATE

Jest inny problem z tym podejściem: jeśli spróbujesz filtrować dane, nie będzie to działać zgodnie z oczekiwaniami. Na przykład, jeśli zrobisz:

SELECT * FROM v_table WHERE field = 'test' AND row BETWEEN 10 AND 20

Gdzie ogranicza się do tych danych, które znajdują się w wierszach od 10 do 20 (zamiast przeszukiwać cały zbiór danych i ograniczać wyjście).

 2
Author: lepe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-17 04:22:49
SELECT TOP 10 * FROM table;

Jest tym samym co

SELECT * FROM table LIMIT 0,10;

Oto artykuł o implementacji limitu w MsSQL to przyjemna lektura, szczególnie komentarze.

 1
Author: Ólafur Waage,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-02 19:56:34

Jest to podejście wieloetapowe, które będzie działać w SQL2000.

-- Create a temp table to hold the data
CREATE TABLE #foo(rowID int identity(1, 1), myOtherColumns)

INSERT INTO #foo (myColumns) SELECT myData order By MyCriteria

Select * FROM #foo where rowID > 10
 1
Author: souLTower,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-02 20:18:10
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;
 1
Author: Julian Moreno,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-28 15:28:12

Muszę spróbować. W poniższym zapytaniu możesz zobaczyć grupy według, kolejność według, Pomiń wiersze i ograniczaj wiersze.

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
 1
Author: M Danish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-12 11:21:31

W SQL nie istnieje słowo kluczowe LIMIT. Jeśli potrzebujesz tylko ograniczonej liczby wierszy, powinieneś użyć słowa kluczowego TOP, które jest podobne do limitu.

 0
Author: Mitul Panchal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-23 05:04:40

Jeśli Twój identyfikator jest unikalnym typem identyfikatora lub Twój Identyfikator w tabeli nie jest posortowany, musisz zrobić tak poniżej.

select * from
(select ROW_NUMBER() OVER (ORDER BY (select 0)) AS RowNumber,* from table1) a
where a.RowNumber between 2 and 5



Kod będzie

select * from limit 2,5
 0
Author: user3244012,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-11 07:09:09

Lepiej Użyj tego w MSSQLExpress 2017.

SELECT * FROM
(
    SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) as [Count], * FROM table1
) as a
WHERE [Count] BETWEEN 10 and 20;

-- podając kolumnę [Count] i przypisując każdemu wierszowi unikalne liczenie bez zamawiania czegoś, a następnie ponownie wybierz ponownie, gdzie możesz podać swoje limity.. :)

 0
Author: user1308314,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-09 01:54:02

Jeden z możliwych sposobów uzyskania wyniku , jak poniżej, mam nadzieję, że to pomoże.

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
 0
Author: Pragnesh Karia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-12-14 10:55:34

Easy way

MYSQL:

SELECT 'filds' FROM 'table' WHERE 'where' LIMIT 'offset','per_page'

MSSQL:

SELECT 'filds' FROM 'table' WHERE 'where' ORDER BY 'any' OFFSET 'offset' 
ROWS FETCH NEXT 'per_page' ROWS ONLY

ORDER BY jest obowiązkowe

 0
Author: Turendu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-03 13:08:26

Jeśli dobrze pamiętam (minęło trochę czasu od kiedy dabbed z SQL Server) możesz być w stanie użyć czegoś takiego: (2005 i w górę)

SELECT
    *
   ,ROW_NUMBER() OVER(ORDER BY SomeFields) AS [RowNum]
FROM SomeTable
WHERE RowNum BETWEEN 10 AND 20
 -2
Author: Kris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-02 20:02:12