Select Star SQL

Code lunghe

Le code lunghe si riferiscono a piccoli numeri di campioni che si verificano un gran numero di volte. Quando li tracciamo, formano un piccolo frammento, che sembra una coda appunto, posizionato molto a destra rispetto al centro di massa. Indicano la presenza di valori anomali che potrebbero interessarci per i loro comportamenti anomali. Nel contesto delle esecuzioni in Texas, la coda lunga si riferisce a un piccolo numero di contee note per aver condotto un gran numero di esecuzioni.

Troviamo la percentuale di esecuzioni per ogni contea in modo da poter individuare quelle in coda.

Come risulterà sempre più evidente, la forma delle tabelle ci può dire molto sulle operazioni che dobbiamo eseguire, in modo analogo a quanto fa l’analisi dimensionale in fisica. In questo caso, possiamo capire che i metodi che abbiamo trattato finora sono inadeguati: il capitolo Beazley trattava singole righe di dati, ma è chiaro che dobbiamo fare qualche aggregazione per trovare i dati a livello di contea. Il capitolo Dichiarazioni di innocenza ci ha insegnato l’aggregazione, ma quelle funzioni finirebbero per aggregare il set di dati in un’unica riga quando in realtà vogliamo una riga per contea.


Il blocco GROUP BY

È qui che entra in gioco il blocco GROUP BY: ci consente di suddividere il set di dati e applicare funzioni aggregate all’interno di ciascun gruppo, ottenendo una riga per gruppo. La sua forma più elementare è GROUP BY <column>, <column>, ... e si posiziona dopo il blocco WHERE.

Se ti ricordi il paragrafo Una query strana, dovrebbero suonare i campanelli d’allarme della tua testa. Non abbiamo appena imparato a non mescolare colonne aggregate e non aggregate? La differenza qui è che le colonne di raggruppamento sono le uniche colonne che possono essere non aggregate. Dopotutto, tutte le righe di quel gruppo devono avere gli stessi valori su quelle colonne, quindi non c’è ambiguità nel valore che deve essere restituito.

Avrai anche notato l’uso di AS: è ciò che noi chiamiamo “alias”. Nel bloccoSELECT, <expression> AS <alias> fornisce un alias a cui è possibile fare riferimento più avanti nella query. Questo ci evita di riscrivere espressioni lunghe e ci permette di scrivere in modo più chiero l’espressione.


Il blocco HAVING

Il prossimo esercizio illustra che il filtraggio tramite il blocco WHERE avviene prima del raggruppamento e dell’aggregazione. Questo si riflette nell’ordine della sintassi poiché il blocco WHERE precede sempre il blocco GROUP BY.

Va tutto bene, ma cosa succede se vogliamo filtrare il risultato del raggruppamento e dell’aggregazione? Sicuramente non possiamo fare un salto nel futuro e prendere informazioni da lì. Per risolvere questo problema, usiamo HAVING.


Pratica

Questo quiz è progettato per mettere alla prova la tua comprensione. Leggi le spiegazioni anche se fai tutto correttamente.


Query annidate

Potresti chiederti se non fosse più semplice scrivere semplicemente qualcosa del genere:

SELECT
  county,
  PERCENT_COUNT(*)
FROM executions
GROUP BY county

Le percentuali sono una misura così comune—non dovrebbe esistere una funzione di questo tipo? Sfortunatamente no, e forse per una buona ragione: una funzione di questo tipo avrebbe bisogno di aggregare i dati sia all’interno dei gruppi (per formare il numeratore) sia su tutto il set di dati (per ottenere il denominatore). Ma ogni query può avere un blocco GROUP BY o no. Quindi quello di cui abbiamo veramente bisogno sono due query distinte una che aggrega i dati con un GROUP BY e una che li aggrega senza. Possiamo poi combinarele con una tecnica che si chiama “nesting”, annidamento in italiano.

Di seguito un esempio di come funziona il nesting. Le parentesi sono importante per identificare i confini fra la query interna e quella esterna:

Per ribadire il concetto, l’annidamento qui è necessario perché nella clausola “WHERE”, mentre il computer ispeziona una riga per decidere se la sua ultima istruzione è della lunghezza giusta, non può guardare all’esterno per determinare la lunghezza massima dell’intero set di dati. Dobbiamo trovare la lunghezza massima separatamente e inserirla nella clausola. Adesso applichiamo lo stesso concetto per trovare la percentuale di esecuzioni in ciascuna contea.

Senza dire nulla ho inserito un blocco ORDER BY. Il suo fomrato è ORDER BY <column>, <column>, ... e può essere modificato aggiungendo DESC se non vuoi l’ordinamento ascendente di default.


Contea di Harris

È sorprendente che le contee di Harris (la contea dove si trova Houston), Dallas, Bexar e Tarrant contano circa il 50% di tutte le esecuzioni del Texas? Forse si, specialmente se partiamo dall’assunto che le esecuzioni dovrebbero essere distribuite uniformemente fra le contee. Ma una approssimazione migliore è che le esecuzioni sono distribuite in linea con la distribuzione di popolazione. Il Censimento del Texas del 2010 mostra che queste quattro contee hanno una popolazione di 10 milioni di persone, che corrisponde al 40.0% della popolazione del Texas (25.1 milioni). Questo rende il dato iniziale meno sorprendente.

Ma analizzando ulteriormente questa coda, si capisce che la contea di Harris contribuisce per la maggior parte di questa variazione. Ha solo il 16.4% della popolazione ma il 23.1% delle esecuzioni: almeno il 50% in più di quello che ci si aspetterebbe.

Molti studi hanno esaminato i motivi per cui la contea di Harris è stata così prolifica e sono stati suggeriti diversi fattori:


In sintesi

In questa sezione abbiamo imparato ad aggregare gruppi e ad utilizzare l’annidamento per utilizzare l’output di una query più interna in una query esterna. Queste tecniche hanno il vantaggio molto pratico di permetterci di calcolare le percentuali.

MapReduce

Un'aggiunta interessante è che in realtà abbiamo appena imparato aa utilizzare MapReduce in SQL. MapReduce è un famoso paradigma di programmazione dove i calcoli avvengono in fasi di "mappa" e "riduci". Puoi imparare di più riguardo MapReduce a questo link.

Il capitolo Beazley è stato tutto sulla mappatura in quanto ci ha mostrato come mappare / eseguire varie operazioni su tutte le righe. Per esempio, SELECT LENGTH(last_statement) FROM executions mappa la funzione di lunghezza su tutte le righe. Questo capitolo ci ha mostrato come ridurre vari gruppi di dati utilizzando le funzioni di aggregazione e il capitolo Possibile innocenza era semplicemente un caso speciale in cui l'intera tabella è un gruppop.

Nel prossimo capitolo impareremo ad utilizzare i JOIN che ci permetteranno di lavorare con più tabelle.