1st Dec 2024 Tempo di lettura: 8 minuti La clausola ORDER BY nelle funzioni SQL Window Tihomir Babic ORDER BY window functions Indice Cosa sono le Window Functions (Funzioni Finestra)? Sintassi Che cos'è la clausola ORDER BY in Window Functions (Funzioni Finestra)? Esempio: ORDER BY con una funzione finestra di classificazione ORDER BY e PARTITION BY in Window Functions (Funzioni Finestra) Esempio: Uso di ORDER BY con PARTITION BY in una funzione finestra ORDER BY in Window Functions (Funzioni Finestra) vs. ORDER BY regolare Esempio: ORDER BY in Window Functions (Funzioni Finestra) e ORDER BY regolare Window Functions (Funzioni Finestra) Che richiedono ORDER BY Cornici di finestra predefinite con e senza ORDER BY Utilizzo di ORDER BY in Window Functions (Funzioni Finestra) In questo articolo viene fornita una panoramica di ORDER BY nelle funzioni di finestra. Imparerete come si differenzia da PARTITION BY e dal normale ORDER BY, il tutto corredato da esempi e spiegazioni. Se volete creare rapporti che vadano oltre le semplici aggregazioni, avete bisogno delle funzioni finestra di SQL. Le funzioni finestra consentono di creare classifiche, calcolare totali e medie mobili e trovare la differenza tra le righe. Per utilizzare le funzioni finestra in modo efficace, è necessario comprendere il ruolo della clausola ORDER BY. Non solo cambia il comportamento delle funzioni finestra, ma alcune funzioni finestra non vengono eseguite senza ORDER BY. Questo articolo è rivolto a chi ha già una conoscenza generale delle funzioni di finestra. Se non le conoscete, vi consiglio vivamente di seguire il nostro corso Window Functions (Funzioni Finestra) . Vi fornirà una conoscenza completa delle funzioni di finestra, comprese le funzioni di classificazione, le funzioni di analisi e le clausole ORDER BY e PARTITION BY. Il corso presenta 218 sfide di codifica che attendono di essere risolte; potete trovarne altre nel set di esercitazioni di Window Functions (Funzioni Finestra) . Anche se conoscete le funzioni SQL a finestra, vi consigliamo di tenere a portata di mano il nostro Window Functions (Funzioni Finestra) Cheat Sheet per una rapida consultazione. Cosa sono le Window Functions (Funzioni Finestra)? Le funzioni finestra in SQL eseguono operazioni su un riquadro di finestra, che consiste nella riga corrente e nelle righe ad essa correlate. A differenza delle funzioni aggregate, le funzioni finestra non comprimono le singole righe, ma aggiungono una colonna a ogni riga con il risultato della funzione. Ciò significa che le funzioni finestra consentono di visualizzare contemporaneamente dati singoli e aggregati. Sintassi La sintassi delle funzioni finestra SQL è illustrata di seguito: window_function OVER ([PARTITION BY column_name] [ORDER BY column_name ASC|DESC]) Ecco una breve descrizione di ogni parte della sintassi: window_function: La funzione finestra che si desidera utilizzare. OVER(): Una clausola obbligatoria per la creazione di una funzione finestra. PARTITION BY: Una clausola opzionale che suddivide i dati. ORDER BY: Una clausola opzionale che ordina i dati all'interno della finestra. Che cos'è la clausola ORDER BY in Window Functions (Funzioni Finestra)? ORDER BY (insieme a PARTITION BY) è una parte fondamentale di molte funzioni finestra. ORDER BY nella funzione finestra ordina le righe all'interno della cornice della finestra. Definisce l'ordine di esecuzione dei calcoli della funzione finestra. ORDER BY può ordinare i dati all'interno di una finestra in modo ascendente (da A a Z, da 1 a 10) o discendente (da Z ad A, da 10 a 1). È possibile ordinare i dati di testo in ordine alfabetico o alfabetico inverso, i dati numerici dal più basso al più alto (o viceversa) e i dati di data/ora dal più vecchio al più recente (o dal più recente al più vecchio). Esempio: ORDER BY con una funzione finestra di classificazione Vediamo un esempio di come ORDER BY nelle funzioni finestra influenza l'esecuzione delle query. La query seguente classifica i dati della tabella product_sales in base alle vendite in ordine decrescente, cioè dalle vendite più alte a quelle più basse. SELECT id, date, sales, product_name, DENSE_RANK() OVER(ORDER BY sales DESC) AS ranking FROM product_sales; DENSE_RANK() è una delle funzioni finestra di classificazione. Essa classifica l'intero set di dati dalle vendite più alte a quelle più basse, specificate in ORDER BY. La tabella originale product_sales originale ha questo aspetto: iddatesalesproduct_name 12024-01-013,548.25Chorizo 22024-01-016,487.26Pierogi 32024-01-018,457.56Gyoza 42024-01-0212,567.44Pierogi 52024-01-021,478.69Chorizo 62024-01-022,489.15Gyoza 72024-01-035,479.99Gyoza 82024-01-038,845.54Chorizo 92024-01-039,748.23Pierogi Pertanto, il codice precedente classifica le righe del set di dati in modo decrescente: dalla più alta alla più bassa. Questo è l'output della query, con i ranghi mostrati in una colonna separata: iddatesalesproduct_nameranking 42024-01-0212,567.44Pierogi1 92024-01-039,748.23Pierogi2 82024-01-038,845.54Chorizo3 32024-01-018,457.56Gyoza4 22024-01-016,487.26Pierogi5 72024-01-035,479.99Gyoza6 12024-01-013,548.25Chorizo7 62024-01-022,489.15Gyoza8 52024-01-021,478.69Chorizo9 Ora, la classifica sarebbe significativamente diversa se si sostituisse DESC con ASC in ORDER BY, come mostrato di seguito: SELECT id, date, sales, product_name, DENSE_RANK() OVER(ORDER BY sales ASC) AS ranking FROM product_sales; Ora la classifica viene eseguita dalle vendite più basse a quelle più alte: iddatesalesproduct_nameranking 52024-01-021,478.69Chorizo1 62024-01-022,489.15Gyoza2 12024-01-013,548.25Chorizo3 72024-01-035,479.99Gyoza4 22024-01-016,487.26Pierogi5 32024-01-018,457.56Gyoza6 82024-01-038,845.54Chorizo7 92024-01-039,748.23Pierogi8 42024-01-0212,567.44Pierogi9 ORDER BY e PARTITION BY in Window Functions (Funzioni Finestra) Sappiamo cosa fa ORDER BY nelle funzioni della finestra. Che dire di PARTITION BY? Si tratta di una clausola opzionale che divide i dati in sottoinsiemi basati su una o più categorie. Lo si fa specificando le colonne nella clausola PARTITION BY in questo modo: PARTITION BY product_name. Ne dimostrerò il funzionamento nella sezione seguente. Senza PARTITION BY, ORDER BY ordina i dati nell'intero insieme di risultati. Se invece lo si usa con PARTITION BY, i dati verranno ordinati separatamente all'interno di ogni partizione. Esempio: Uso di ORDER BY con PARTITION BY in una funzione finestra Se utilizzato con PARTITION BY, ORDER BY ordina i dati all'interno di ogni partizione. L'uso di ORDER BY con la funzione finestra SUM() produce una somma cumulativa (cioè la somma del valore della riga corrente più tutte le righe precedenti nella partizione). Ad esempio, il codice seguente calcola la somma cumulativa delle vendite per nome di prodotto (come specificato in PARTITION BY) dalla data più vecchia a quella più recente (come specificato in ORDER BY). SELECT id, date, sales, product_name, SUM(sales) OVER(PARTITION BY product_name ORDER BY date ASC) AS cumulative_sum FROM product_sales; La query dividerà innanzitutto il set di dati in partizioni per nome di prodotto. Quindi i valori all'interno di ogni partizione saranno ordinati dalla data più vecchia a quella più recente, specificata in ORDER BY. Quindi la funzione SUM() window calcolerà il totale cumulativo sommando le vendite della data corrente con le vendite di tutte le vendite precedenti all'interno della partizione. Ecco l'output, che mostra ogni riga e le vendite cumulative per ogni prodotto: iddatesalesproduct_namecumulative_sum 12024-01-013,548.25Chorizo3,548.25 52024-01-021,478.69Chorizo5,026.94 82024-01-038,845.54Chorizo13,872.48 32024-01-018,457.56Gyoza8,457.56 62024-01-022,489.15Gyoza10,946.71 72024-01-035,479.99Gyoza16,426.70 22024-01-016,487.26Pierogi6,487.26 42024-01-0212,567.44Pierogi19,054.70 92024-01-039,748.23Pierogi28,802.93 Se si rimuove ORDER BY dal codice, come mostrato di seguito... SELECT id, date, sales, product_name, SUM(sales) OVER(PARTITION BY product_name) AS cumulative_sum FROM product_sales; ... il codice restituirà la somma delle vendite totali per ciascun prodotto. In altre parole, omettendo semplicemente ORDER BY da una funzione finestra, si perde la capacità di calcolare in modo cumulativo. Senza ORDER BY, tutte le righe della partizione costituiscono la cornice della finestra. iddatesalesproduct_namecumulative_sum 12024-01-013,548.25Chorizo13,872.48 52024-01-021,478.69Chorizo13,872.48 82024-01-038,845.54Chorizo13,872.48 62024-01-022,489.15Gyoza16,426.70 72024-01-035,479.99Gyoza16,426.70 32024-01-018,457.56Gyoza16,426.70 42024-01-0212,567.44Pierogi28,802.93 92024-01-039,748.23Pierogi28,802.93 22024-01-016,487.26Pierogi28,802.93 ORDER BY in Window Functions (Funzioni Finestra) vs. ORDER BY regolare Quando si parla di ordine regolare, si intende l'ordine standard di ORDER BY alla fine della query. In che modo è diverso da ORDER BY in una funzione finestra? Un ORDER BY regolare ordina l'output di una query, mentre ORDER BY nelle funzioni finestra ordina una finestra di dati o una partizione di dati. Esempio: ORDER BY in Window Functions (Funzioni Finestra) e ORDER BY regolare Questa query utilizza la funzione finestra DENSE_RANK() con PARTITION BY e ORDER BY per classificare le date di vendita di ciascun prodotto: SELECT id, date, sales, product_name, DENSE_RANK() OVER(PARTITION BY product_name ORDER BY sales DESC) AS day_rank FROM product_sales; Si può notare che l'output complessivo non è ordinato dalle vendite più alte a quelle più basse. L'ordinamento decrescente delle date viene applicato solo all'interno di ogni partizione. iddatesalesproduct_namesales_rank_by_product 82024-01-038,845.54Chorizo1 12024-01-013,548.25Chorizo2 52024-01-021,478.69Chorizo3 32024-01-018,457.56Gyoza1 72024-01-035,479.99Gyoza2 62024-01-022,489.15Gyoza3 42024-01-0212,567.44Pierogi1 92024-01-039,748.23Pierogi2 22024-01-016,487.26Pierogi3 Se si desidera che l'output sia ordinato in modo decrescente in base alle vendite, è necessario farlo esplicitamente aggiungendo ORDER BY alla fine della query: SELECT id, date, sales, product_name, DENSE_RANK() OVER(PARTITION BY product_name ORDER BY sales DESC) AS sales_rank_by_product FROM product_sales ORDER BY sales DESC; Ora si ottiene l'output ordinato per vendite e data. È possibile vedere come la classifica delle vendite di una data si confronta con le vendite dello stesso prodotto in altre date. iddatesalesproduct_namesales_rank_by_product 42024-01-0212,567.44Pierogi1 92024-01-039,748.23Pierogi2 82024-01-038,845.54Chorizo1 32024-01-018,457.56Gyoza1 22024-01-016,487.26Pierogi3 72024-01-035,479.99Gyoza2 12024-01-013,548.25Chorizo2 62024-01-022,489.15Gyoza3 52024-01-021,478.69Chorizo3 Window Functions (Funzioni Finestra) Che richiedono ORDER BY Come si è visto nell'esempio precedente, le funzioni finestra possono funzionare anche senza ORDER BY. ORDER BY è generalmente considerata una clausola opzionale nelle funzioni finestra. Ma anche se ORDER BY nelle funzioni finestra è considerata una clausola opzionale, alcune funzioni finestra richiedono ORDER BY per funzionare. In questi casi, ORDER BY diventa obbligatorio; queste funzioni di finestra richiedono un ordine di ordinamento per funzionare correttamente. Queste funzioni sono: RANK() DENSE_RANK() NTILE() LEAD() LAG() Cornici di finestra predefinite con e senza ORDER BY Il comportamento di una funzione finestra cambia a seconda che sia scritta con o senza ORDER BY. Più precisamente, la presenza o l'assenza di ORDER BY influisce sulla cornice predefinita della finestra. Se non c'è ORDER BY, la cornice predefinita della finestra include la riga corrente e tutte le righe precedenti e successive. In altre parole, tutte le righe della partizione sono incluse. Lo abbiamo visto con l'esempio della somma cumulativa: senza ORDER BY, il riquadro della finestra si riferisce all'intera partizione e la somma diventa la somma totale. Se è presente ORDER BY, la finestra include il valore corrente e tutti i valori precedenti. Lo abbiamo visto con l'esempio della somma cumulativa: con ORDER BY, il riquadro della finestra include tutte le righe precedenti alla riga corrente e la riga corrente. Se non si gradisce la finestra predefinita, è possibile definirla esplicitamente utilizzando le parole chiave ROWS e RANGE. Utilizzo di ORDER BY in Window Functions (Funzioni Finestra) Ecco come funziona: ORDER BY - a volte obbligatoria, a volte facoltativa - è la clausola che fa e a volte fa fallire le funzioni delle finestre. Tuttavia, sapere tutto su ORDER BY nelle funzioni finestra non serve a nulla se non è possibile utilizzarlo nelle query. Verificate quindi quanto appreso qui risolvendo le sfide di codifica del nostro corso sulle funzioni finestra e del set di esercitazioni Window Functions (Funzioni Finestra) . Per ulteriori esercizi, risolvete questi 11 esercizi sulle funzioni finestra e rispondete alle 10 migliori domande di intervista sulle funzioni finestra. Buon apprendimento! Tags: ORDER BY window functions