2012-11-04 12 views
72

Ho cercato di capire un po 'come implementare il paging personalizzato in SQL, ad esempio leggendo articles like this one.Implementare la funzionalità di paging (skip/take) con questa query

Ho la seguente query, che funziona perfettamente. Ma vorrei implementare il paging con questo.

SELECT TOP x PostId FROM (SELECT PostId, MAX (Datemade) as LastDate 
from dbForumEntry 
group by PostId) SubQueryAlias 
order by LastDate desc 

cosa è che voglio

devo post del forum, con voci correlate. Voglio ricevere i post con le ultime voci aggiunte, così posso selezionare i post di recente discussione.

Ora, voglio essere in grado di ottenere i "primi 10 o 20 messaggi attivi di recente", anziché "primi 10".

Che ho io provato

Ho cercato di implementare le funzioni fila come quello in questo articolo, ma in realtà senza fortuna.

Qualche idea su come implementarlo?

risposta

161

In SQL Server 2012 è molto molto facile

SELECT col1, col2, ... 
FROM ... 
WHERE ... 
ORDER BY -- this is a MUST there must be ORDER BY statement 
-- the paging comes here 
OFFSET  10 ROWS  -- skip 10 rows 
FETCH NEXT 10 ROWS ONLY; -- take 10 rows 

Se vogliamo ignorare ORDER BY possiamo usare

SELECT col1, col2, ... 
    ... 
ORDER BY CURRENT_TIMESTAMP 
OFFSET  10 ROWS  -- skip 10 rows 
FETCH NEXT 10 ROWS ONLY; -- take 10 rows 

(preferirei contrassegnare che, come un hack - ma è utilizzato, ad esempio, da NHibernate.Per utilizzare una colonna saggiamente prelevata come ORDER BY è preferibile)

a rispondere alla domanda:

--SQL SERVER 2012 
SELECT PostId FROM 
     (SELECT PostId, MAX (Datemade) as LastDate 
      from dbForumEntry 
      group by PostId 
     ) SubQueryAlias 
order by LastDate desc 
OFFSET 10 ROWS -- skip 10 rows 
FETCH NEXT 10 ROWS ONLY; -- take 10 rows 

Nuove parole chiave offset e fetch next (solo seguendo standard SQL) sono stati introdotti.

Ma immagino, che non si utilizza SQL Server 2012 , giusto? Nella versione precedente è un po '(un po') difficile. Ecco il confronto ed esempi per tutte le versioni di SQL Server: here

Quindi, questo potrebbe funzionare in SQL Server 2008:

-- SQL SERVER 2008 
DECLARE @Start INT 
DECLARE @End INT 
SELECT @Start = 10,@End = 20; 


;WITH PostCTE AS 
(SELECT PostId, MAX (Datemade) as LastDate 
    ,ROW_NUMBER() OVER (ORDER BY PostId) AS RowNumber 
    from dbForumEntry 
    group by PostId 
) 
SELECT PostId, LastDate 
FROM PostCTE 
WHERE RowNumber > @Start AND RowNumber <= @End 
ORDER BY PostId 
+0

Grazie mille! Questa è davvero una buona risposta! Unica domanda su SQL 2008. Voglio che l'ORDER BY avvenga prima del WHERE, poiché al momento selezionerà il sottoinsieme, ma vogliamo selezionare qualcosa dell'intero set ... Qualche idea? :) Ancora una volta, grazie –

+2

Se ho capito bene, ti piacerebbe ordinare per LastDate, giusto? quindi possiamo modificare la clausola OVER() in questo modo: ROW_NUMBER() OVER (ORDER BY ** MAX (Datemade) desc **). * E rimuovi l'ultimo ORDER BY PostId *. Ora il CTE dovrebbe essere ordinato 'prima' se necessario. corretta? –

+1

Grazie a questo, una nota sull'esempio del 2012, l'ordine per è obbligatorio, stavo provando questo senza ordine per clausola e ho ricevuto l'errore "sintassi errata" non avevo idea di cosa non andava fino a quando non osservavo la sintassi MSDN e ho imparato che l'ordine è obbligatorio. – Esen

4

Per fare questo in SQL Server, è necessario ordinare la query una colonna, quindi è possibile specificare le righe che si desidera.

Esempio:

select * from table order by [some_column] 
offset 10 rows 
FETCH NEXT 10 rows only 

E non è possibile utilizzare la parola chiave "TOP" quando si fa questo.

Potete saperne di più qui: https://technet.microsoft.com/pt-br/library/gg699618%28v=sql.110%29.aspx

1
OFFSET  10 ROWS  -- skip 10 rows 
FETCH NEXT 10 ROWS ONLY; -- take 10 rows 

uso questo, alla fine della vostra sintassi select. =)

0

È possibile utilizzare Query nidificate per impaginazione come segue: Paging da 4 righe a 8 righe in cui CustomerId è chiave primaria

SELEZIONA Top 5 * DA Clienti DOVE Paese = 'Germania' E Cliente non in (SELEZIONA Top 3 ID cliente dai clienti DOVE Paese = 'Germania' ordina per città) ordina per città;

Problemi correlati