Una delle nuove funzionalità di PostgreSQL 13 è lo standard SQL WITH TIES
clausola da utilizzare con LIMIT
— o, come lo standard lo chiama, FETCH FIRST n ROWS
. I ringraziamenti sono dovuti a Surafel Temesgen come autore iniziale della patch; Tomas Vondra e il tuo veramente per alcune correzioni di codice aggiuntive; e i revisori Andrew Gierth ed Erik Rijkers. Puoi esaminare il messaggio di commit.
I pareggi sono molto frequenti quando si classificano le cose; ad esempio, in una gara di caucus potresti avere molti pareggi, e di sicuro non vuoi privare i partecipanti dei loro premi! Cosa WITH TIES
do è piuttosto semplice:aggiunge qualsiasi riga o riga successiva al set di risultati, se si classifica uguale all'ultima riga restituita per LIMIT
clausola, secondo il ORDER BY
clausola.
Se vuoi solo i due dipendenti con lo stipendio più alto, puoi farlo:
SELECT * FROM employees ORDER BY salary DESC LIMIT 2;
nome | stipendio | reparto |
---|---|---|
Alice | 1600 | ingegneria |
Oruga | 1500 | marketing |
Quindi non vedi l'ora di sapere lo stipendio della prossima persona? E se fosse all'altezza di Oruga e fosse stata esclusa per puro caso o sfortuna? Può succedere, come ben sai; e fortunatamente, WITH TIES
è ora lì per salvare la giornata. (Nota che, in realtà, non gestiamo WITH TIES
nel LIMIT
clausola in quanto tale. Devi usare il FETCH FIRST
sintassi, che è quella standard, per poter usare WITH TIES
.)
SELECT * FROM employees ORDER BY salary DESC FETCH FIRST 2 ROWS WITH TIES;
nome | stipendio | reparto |
---|---|---|
Alice | 1600 | ingegneria |
Oruga | 1500 | vendite |
Conejo Blanco | 1500 | marketing |
Là! White Rabbit aveva essere elencato, e ora lo è.
Un paio di appunti prima di impazzire troppo. LIMIT
(o più precisamente FETCH FIRST
) non promette più di restituire esattamente il numero di righe specificato. Potresti ottenere due o venti righe aggiuntive o 100 volte il numero di righe richiesto. Tra le altre cose, questo significa che devi tenere traccia di quante righe hai visto finora, se stai impaginando i risultati. In quanto sopra, hai tre righe, quindi per la pagina successiva ne salti tante aggiungendo il giusto OFFSET
clausola:
SELECT * FROM employees
ORDER BY salary DESC
FETCH FIRST 2 ROWS WITH TIES
OFFSET 3;
nome | stipendio | reparto |
---|---|---|
Falsa Tortuga | 1400 | marketing |
Duquesa | 1300 | vendite |
Legge di marzo | 1300 | ingegneria |
Ne abbiamo presi di nuovo tre anziché solo due che avevamo chiesto. Quindi per la pagina successiva dovresti saltarne sei. E così via. Assicurati di avere abbastanza ditali per tutti.
L'altra cosa da tenere a mente è che devi assicurarti di utilizzare solo ORDER BY
clausola che si adatta al WITH TIES
clausola; se volessi, diciamo, avere le righe dello stesso stipendio ordinate per nome, dovresti usare una sottoquery. In caso contrario, la distinzione dei nomi risolverebbe il pareggio sullo stipendio, quindi la riga successiva non verrebbe inclusa. Ad esempio:
SELECT * FROM (
SELECT * FROM employees
ORDER BY salary DESC
FETCH FIRST 2 ROWS WITH TIES) AS subq
ORDER BY salary DESC, name;
Questa funzione è lì per aiutarti a mostrare tutte le righe che hanno lo stesso valore:ti consente di non discriminare alcune righe di valore uguale in base esclusivamente alla posizione fisica all'interno della tabella.
Buona impaginazione!