risposta-alla-domanda-sullo-sviluppo-web-bd.com

LIMIT 10..20 in SQL Server

Sto cercando di fare qualcosa del tipo:

SELECT * FROM table LIMIT 10,20

o

SELECT * FROM table LIMIT 10 OFFSET 10

ma usando SQL Server

L'unico soluzione che ho trovato sembra eccessivo:

SELECT * FROM ( 
  SELECT *, ROW_NUMBER() OVER (ORDER BY name) as row FROM sys.databases 
 ) a WHERE row > 5 and row <= 10

Ho anche trovato :

SELECT TOP 10 * FROM stuff; 

... ma non è quello che voglio fare poiché non riesco a specificare il limite iniziale.

C'è un altro modo per farlo?

Inoltre, solo curioso, c'è un motivo per cui SQL Server non supporta la funzione LIMIT o qualcosa di simile? Non voglio essere cattivo, ma sembra davvero qualcosa di cui un DBMS ha bisogno ... Se lo fa, allora mi dispiace di essere così ignorante! Ho lavorato con MySQL e SQL + negli ultimi 5 anni, quindi ...

154
marcgg

La clausola LIMIT non fa parte di SQL standard. È supportato come estensione del fornitore per SQL da MySQL, PostgreSQL e SQLite.

Altre marche di database possono avere caratteristiche simili (ad esempio TOP in Microsoft SQL Server), ma queste non funzionano sempre in modo identico.

È difficile utilizzare TOP in Microsoft SQL Server per imitare la clausola LIMIT. Ci sono casi in cui semplicemente non funziona.

La soluzione che hai mostrato, usando ROW_NUMBER() è disponibile in Microsoft SQL Server 2005 e versioni successive. Questa è la soluzione migliore (per ora) che funziona esclusivamente come parte della query.

Un'altra soluzione è utilizzare TOP per recuperare le prime count + offset righe , quindi utilizza l'API per cercare oltre le prime offset righe.

Guarda anche:

100
Bill Karwin

Per SQL Server 2012 + è possibile utilizzare .

SELECT  *
FROM     sys.databases
ORDER BY name 
OFFSET  5 ROWS 
FETCH NEXT 5 ROWS ONLY 
122
Martin Smith

come hai trovato, questo è il metodo SQL Server preferito:

SELECT * FROM ( 
  SELECT *, ROW_NUMBER() OVER (ORDER BY name) as row FROM sys.databases 
 ) a WHERE a.row > 5 and a.row <= 10
34
KM.

Se si utilizza il voto di SQL Server 2012+ per la risposta di Martin Smith e si utilizzano le estensioni OFFSET e FETCH NEXT per ORDER BY,

Se sei abbastanza sfortunato da rimanere bloccato con una versione precedente, potresti fare qualcosa del genere,

WITH Rows AS
(
    SELECT
              ROW_NUMBER() OVER (ORDER BY [dbo].[SomeColumn]) [Row]
            , *
        FROM
              [dbo].[SomeTable]
)
SELECT TOP 10
          *
     FROM
         Rows
    WHERE Row > 10

Credo funzionalmente equivalente a

SELECT * FROM SomeTable LIMIT 10 OFFSET 10 ORDER BY SomeColumn

e il modo migliore che conosco per farlo in TSQL, prima di MS SQL 2012.


Se sono presenti molte righe, è possibile ottenere prestazioni migliori utilizzando una tabella temporanea anziché un CTE.

10
Jodrell

Sfortunatamente, ROW_NUMBER() è il meglio che puoi fare. In realtà è più corretto, perché i risultati di una clausola limit o top non hanno davvero significato senza rispetto di un ordine specifico. Ma è ancora un dolore da fare.

Aggiornamento: SQL Server 2012 aggiunge una funzione simile a limit tramite parole chiave OFFSET e FETCH . Questo è l'approccio ansi standard, al contrario di LIMIT, che è un'estensione MySql non standard.

7
Joel Coehoorn

Cosa ne pensi di questo?

SET ROWCOUNT 10 

SELECT TOP 20 *
FROM sys.databases
ORDER BY database_id DESC

Ti dà le ultime 10 righe delle prime 20 righe. Uno svantaggio è che l'ordine è invertito, ma almeno è facile da ricordare.

5
David Patrick
SELECT TOP 10 *
FROM TABLE
WHERE IDCOLUMN NOT IN (SELECT TOP 10 IDCOLUMN FROM TABLE)

Dovrebbe dare record 11-20. Probabilmente non troppo efficiente se si incrementa per ottenere ulteriori pagine, e non sono sicuro di come potrebbe essere influenzato dall'ordinamento. Potrebbe essere necessario specificarlo in entrambe le istruzioni WHERE.

2
Andy

Solo per la soluzione record che funziona sulla maggior parte dei motori di database potrebbe non essere la più efficiente:

Select Top (ReturnCount) *
From (
    Select Top (SkipCount + ReturnCount) *
    From SourceTable
    Order By ReverseSortCondition
) ReverseSorted
Order By SortCondition

Nota Pelase: l'ultima pagina conterrebbe comunque le righe ReturnCount, indipendentemente da SkipCount. Ma potrebbe essere una buona cosa in molti casi.

1
Y.B.

Un buon modo è quello di creare una procedura:

create proc pagination (@startfrom int ,@endto int) as
SELECT * FROM ( 
  SELECT *, ROW_NUMBER() OVER (ORDER BY name desc) as row FROM sys.databases 
 ) a WHERE a.row > @startfrom and a.row <= @endto

proprio come limite 0,2 /////////////// eseguire l'impaginazione 0,4

1
Wahaj Latif

L'equivalente di LIMIT è SET ROWCOUNT, ma se si desidera l'impaginazione generica è meglio scrivere una query come questa:

;WITH Results_CTE AS
(
    SELECT
        Col1, Col2, ...,
        ROW_NUMBER() OVER (ORDER BY SortCol1, SortCol2, ...) AS RowNum
    FROM Table
    WHERE <whatever>
)
SELECT *
FROM Results_CTE
WHERE RowNum >= @Offset
AND RowNum < @Offset + @Limit
1

Usa tutto il server SQL:; con tbl as (SELECT ROW_NUMBER () su (ordina per (seleziona 1)) come RowIndex, * dalla tabella) seleziona i primi 10 * da tbl dove RowIndex> = 10

0

Dalla documentazione online di MS SQL Server ( http://technet.Microsoft.com/en-us/library/ms186734.aspx ), ecco il loro esempio che ho testato e funziona, per recuperare un set specifico di righe. ROW_NUMBER richiede un OVER, ma puoi ordinare come preferisci:

WITH OrderedOrders AS
(
  SELECT SalesOrderID, OrderDate,
  ROW_NUMBER() OVER (ORDER BY OrderDate) AS RowNumber
  FROM Sales.SalesOrderHeader 
) 
SELECT SalesOrderID, OrderDate, RowNumber  
FROM OrderedOrders 
WHERE RowNumber BETWEEN 50 AND 60;
0
Shannon WM

Finora questo formato è ciò che funziona per me (non la migliore performance però):

SELECT TOP {desired amount of rows} * 
FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY {order columns} asc)__row__ FROM {table})tmp
WHERE __row__ > {offset row count}

Una nota a lato, l'impaginazione su dati dinamici può portare a risultati strani/imprevisti.

0
select * from (select id,name,ROW_NUMBER() OVER (ORDER BY id  asc) as row
from tableName1) tbl1
where tbl1.row>=10 and tbl1.row<=15

Stampa le righe da 10 a 15.

0
sjith