Paginazione dei dati

Paginazione con altri RDBMS

Abbiamo detto in precedenza che lo standard SQL non prevede una sintassi per ottenere solo una parte dei record estratti da una SELECT. Inoltre abbiamo visto come MySQL adotti una soluzione proprietaria attraverso le clausole LIMIT e OFFSET.

Del resto MySQL non è l'unico RDBMS con cui PHP può interagire quindi vediamo ora come risolvere il problema dell'estrazione di una pagina di dati con i più diffusi database relazionali.

PostgreSQL e SQLite adottano una sintassi molto simile a quella di MySQL, basata su LIMIT e OFFSET:

SELECT ... LIMIT n OFFSET m

Maggiori informazioni si trovano sulle rispettive documentazioni ufficiali:

http://www.postgresql.org/docs/8.2/interactive/queries-limit.html

http://www.sqlite.org/lang_select.html

Oracle, Microsoft SQL Server e IBM DB2 invece non adottano una sintassi particolare per l'estrazione paginata dei dati pertanto è necessario adottare qualche stratagemma.

Con Microsoft SQL Server 2005 è stata introdotta la funzione ROW_NUMBER() in grado di assegnare un numero crescente ad ogni record estratto dalla SELECT secondo il particolare ordinamento dichiarato. Grazie a questo numero è poi possibile utilizzare la clausola WHERE per selezionare i record da estrarre:

SELECT *
  FROM (
       SELECT TOP 30 ROW_NUMBER() OVER (ORDER BY ...) AS row, ... FROM ...
       ) AS tab1
  WHERE row >= 21 AND row <= 30

Il TOP 30 serve a migliorare le prestazioni della SELECT più interna, poiché indica al DB che siamo interessati solo alle prime 30 righe.

Con le versioni precedenti di Microsoft SQL Server è necessario seguire altre strategie, ad esempio la seguente che fa uso del SELECT TOP e dell'inversione dell'ordinamento

SELECT *
   FROM (
      SELECT TOP 10 *
          FROM (
                  SELECT TOP 30 ... FROM ...ORDER BY ... ASC
          ) AS inner_tbl
          ORDER BY DESC
    ) AS outer_tbl
    ORDER BY ... ASC

Con Oracle possiamo seguire 2 principali tecniche, una basata sul ROWNUM e l'altra sulla funzione ROW_NUMBER(). Di seguito viene riportato un esempio per ciascuna tecnica, seguito da un link utile per ottenere maggiori informazioni.

SELECT tab2.*
            FROM (
                SELECT ROWNUM AS rn, tab1.*
                FROM (
                    SELECT ... FROM ... WHERE ... ORDER BY ...
                ) tab1
            ) tab2
            WHERE tab2.rn BETWEEN 21 AND 30

http://www.oracle.com/technology/oramag/oracle/06-sep/o56asktom.html

oppure

SELECT *
   FROM (
      SELECT ..., ROW_NUMBER() OVER(ORDER BY ...) rn FROM ...
   )
   WHERE rn BETWEEN 21 and 30
ORDER BY rn

http://www.oracle.com/technology/oramag/oracle/07-jan/o17asktom.html

Anche IBM DB2 possiede la funzione ROW_NUMBER(), pertanto possiamo utilizzare un approccio simile a quelli visti in precedenza.

SELECT *
   FROM
   (
      SELECT ..., ROW_NUMBER() OVER (ORDER BY ...) AS rn FROM ...
    ) AS tab1
   WHERE rn BETWEEN 21 AND 30;
Pagine: precedente 1 ... 3 4 5 67

3 commenti

1 Roberta Roberta mercoledì 12 maggio 2010, ore 08:27
Ciao sto usando il tuo codice per fare la paginazione in un mio sito però ho dei problemi, non segnala nessun errore ma non compaiono i numeri linkabili di conseguenza non posso navigare tra le vaie pagine è come se non funzionasse la funzione paginazione eppure io ho fatto copia incolla del codice e l'ho adattato al mio sito cosa sbaglio?
2 Roberta Roberta mercoledì 12 maggio 2010, ore 09:47
nn metevo l'echo alla fine scusa tutto ok il codice è perfetto
3 stefana stefana sabato 15 gennaio 2011, ore 20:13
magnifico...funziona...solo una questione....se voglio limitare la paginazione solo a 30 records su 60 per esempio e che quindi nella visualizzazione vengono conteggiati solo i 30 ( a partire dal primo records...o anche nel caso si debba partire dal 10...a seconda dei dati che ho bisogno di visualizzare nella pagina) come devo fare???? quali parametri sono da correggere?????
Effettua l'accesso o registrati per inserire un commento