In PostgreSQL sono presenti le parole chiave Limite Offsetche consentono una paginazione molto semplice dei set di risultati.
Qual è la sintassi equivalente per SQL Server?
In PostgreSQL sono presenti le parole chiave Limite Offsetche consentono una paginazione molto semplice dei set di risultati.
Qual è la sintassi equivalente per SQL Server?
Risposte:
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
Il vantaggio qui è la parametrizzazione dell'offset e del limite nel caso in cui si decida di modificare le opzioni di paginazione (o consentire all'utente di farlo).
Nota: il @Offsetparametro dovrebbe utilizzare l'indicizzazione basata su uno per questo anziché la normale indicizzazione basata su zero.
WHERE RowNum >= (@Offset + 1)
The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP or FOR XML is also specified. MSSQL2008 R2.
Tableha 200k record, recupererà prima tutto, quindi applicherà il limite? Questa query è efficiente?
Questa funzionalità è ora semplificata in SQL Server 2012. Funziona da SQL Server 2012 in poi.
Limita con offset per selezionare da 11 a 20 righe in SQL Server:
SELECT email FROM emailTable
WHERE user_id=3
ORDER BY Id
OFFSET 10 ROWS
FETCH NEXT 10 ROWS ONLY;
OFFSET: numero di righe saltateNEXT: numero richiesto di righe successiveRiferimento: https://docs.microsoft.com/en-us/sql/t-sql/queries/select-order-by-clause-transact-sql?view=sql-server-2017
SQL_CALC_FOUND_ROWSquando si utilizza questo?
select top {LIMIT HERE} * from (
select *, ROW_NUMBER() over (order by {ORDER FIELD}) as r_n_n
from {YOUR TABLES} where {OTHER OPTIONAL FILTERS}
) xx where r_n_n >={OFFSET HERE}
Nota:
questa soluzione funzionerà solo in SQL Server 2005 o versioni successive, poiché era in quel momento che era ROW_NUMBER()stata implementata.
AS xx
Per me l'uso di OFFSET e FETCH insieme è stato lento, quindi ho usato una combinazione di TOP e OFFSET come questa (che era più veloce):
SELECT TOP 20 * FROM (SELECT columname1, columname2 FROM tablename
WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS) aliasname
Nota: se si utilizzano TOP e OFFSET insieme nella stessa query come:
SELECT TOP 20 columname1, columname2 FROM tablename
WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS
Quindi viene visualizzato un errore, quindi per utilizzare TOP e OFFSET insieme è necessario separarlo con una query secondaria.
E se è necessario utilizzare SELECT DISTINCT, la query è simile a:
SELECT TOP 20 FROM (SELECT DISTINCT columname1, columname2
WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS) aliasname
Nota: l'uso di SELECT ROW_NUMBER con DISTINCT non ha funzionato per me.
SELECT TOP 20 id FROM table1 where id > 10 order by date OFFSET 20 rows, devi trasformarlo come SELECT TOP 20 * FROM (SELECT id FROM table1 where id > 10 order by date OFFSET 20 ROWS) t1. Modificherò la mia risposta. Grazie e mi scusi il mio inglese.
Un altro campione:
declare @limit int
declare @offset int
set @offset = 2;
set @limit = 20;
declare @count int
declare @idxini int
declare @idxfim int
select @idxfim = @offset * @limit
select @idxini = @idxfim - (@limit-1);
WITH paging AS
(
SELECT
ROW_NUMBER() OVER (order by object_id) AS rowid, *
FROM
sys.objects
)
select *
from
(select COUNT(1) as rowqtd from paging) qtd,
paging
where
rowid between @idxini and @idxfim
order by
rowid;
C'è qui qualcuno dire su questa funzionalità in SQL 2011, la sua triste scelgono un po 'parola chiave diversa "Offset / fetch", ma la sua non standart quindi OK.
Aggiungendo una leggera variazione alla soluzione di Aaronaught, in genere parametrizzo il numero di pagina (@PageNum) e le dimensioni della pagina (@PageSize). In questo modo ogni evento di clic sulla pagina invia semplicemente il numero di pagina richiesto insieme a una dimensione di pagina configurabile:
begin
with My_CTE as
(
SELECT col1,
ROW_NUMBER() OVER(ORDER BY col1) AS row_number
FROM
My_Table
WHERE
<<<whatever>>>
)
select * from My_CTE
WHERE RowNum BETWEEN (@PageNum - 1) * (@PageSize + 1)
AND @PageNum * @PageSize
end
Il più vicino che potessi fare è
select * FROM( SELECT *, ROW_NUMBER() over (ORDER BY ID ) as ct from [db].[dbo].[table] ) sub where ct > fromNumber and ct <= toNumber
Che immagino simile select * from [db].[dbo].[table] LIMIT 0, 10
-- @RowsPerPage can be a fixed number and @PageNumber number can be passed
DECLARE @RowsPerPage INT = 10, @PageNumber INT = 2
SELECT *
FROM MemberEmployeeData
ORDER BY EmployeeNumber
OFFSET @PageNumber*@RowsPerPage ROWS
FETCH NEXT 10 ROWS ONLY
@nombre_row :nombre ligne par page
@page:numero de la page
//--------------code sql---------------
declare @page int,@nombre_row int;
set @page='2';
set @nombre_row=5;
SELECT *
FROM ( SELECT ROW_NUMBER() OVER ( ORDER BY etudiant_ID ) AS RowNum, *
FROM etudiant
) AS RowConstrainedResult
WHERE RowNum >= ((@page-1)*@nombre_row)+1
AND RowNum < ((@page)*@nombre_row)+1
ORDER BY RowNum
Poiché nessuno ha ancora fornito questo codice:
SELECT TOP @limit f1, f2, f3...
FROM t1
WHERE c1 = v1, c2 > v2...
AND
t1.id NOT IN
(SELECT TOP @offset id
FROM t1
WHERE c1 = v1, c2 > v2...
ORDER BY o1, o2...)
ORDER BY o1, o2...
Punti importanti:
@limit può essere sostituito con il numero di risultati da recuperare,@offset è il numero di risultati da saltarewhereeorder by clausole e fornirà risultati errati se non sono sincronizzatiorder byc'è esplicitamente se questo è ciò che è necessarioIn particolare per SQL-SERVER puoi ottenerlo in molti modi diversi. Per un vero esempio abbiamo preso la tabella dei clienti qui.
Esempio 1: con "SET ROWCOUNT"
SET ROWCOUNT 10
SELECT CustomerID, CompanyName from Customers
ORDER BY CompanyName
Per restituire tutte le righe, impostare ROWCOUNT su 0
SET ROWCOUNT 0
SELECT CustomerID, CompanyName from Customers
ORDER BY CompanyName
Esempio 2: con "ROW_NUMBER e OVER"
With Cust AS
( SELECT CustomerID, CompanyName,
ROW_NUMBER() OVER (order by CompanyName) as RowNumber
FROM Customers )
select *
from Cust
Where RowNumber Between 0 and 10
Esempio 3: con "OFFSET e FETCH", ma con questo "ORDER BY" è obbligatorio
SELECT CustomerID, CompanyName FROM Customers
ORDER BY CompanyName
OFFSET 0 ROWS
FETCH NEXT 10 ROWS ONLY
Spero che questo ti aiuti.
Da allora, ho testato più volte questo script più utile di 1 milione di record ogni pagina 100 record con l'impaginazione funzionano più velocemente il mio PC esegue questo script 0 sec mentre il confronto con mysql ha il proprio limite e lo scostamento di circa 4,5 sec per ottenere il risultato.
Qualcuno potrebbe perdere la comprensione di Row_Number () ordinare sempre per campo specifico. Nel caso in cui abbiamo bisogno di definire solo la riga in sequenza dovrebbe usare:
SELECT TOP {LIMIT} * FROM (
SELECT TOP {LIMIT} + {OFFSET} ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS ROW_NO,*
FROM {TABLE_NAME}
) XX WHERE ROW_NO > {OFFSET}
Spiegare: