MySQL Clausole GROUP BY e HAVING con esempi

โšก Riepilogo intelligente

Le clausole SQL GROUP BY e HAVING trasformano le righe dettagliate in report di riepilogo. GROUP BY raggruppa le righe che condividono gli stessi valori in un'unica riga per gruppo, mentre HAVING filtra tali gruppi dopo l'applicazione di funzioni di aggregazione come COUNT.

  • ๐Ÿ“Š Scopo principale: GROUP BY raggruppa le righe con valori identici e restituisce una singola riga per ogni elemento raggruppato.
  • ๐Ÿงฉ Gruppo a colonna singolaping: Grouping La tabella dei membri relativa al genere comprime nove righe in due, una per le donne e una per gli uomini.
  • ๐Ÿ”— Gruppo di colonne multipleping: Grouping su due colonne considera una riga come univoca quando almeno uno dei valori รจ diverso, quindi vengono raggruppati solo i duplicati esatti.
  • ๐Ÿงฎ Accoppiamento aggregato: CONTA, SOMMA, AVGMIN e MAX calcolano un valore per gruppo, che produce il report di riepilogo.
  • ๐Ÿšฆ AVERE contro DOVE: WHERE filtra le righe prima del raggruppamentoping, HAVING filtra i gruppi successivamente e solo HAVING accetta i risultati aggregati.
  • โš ๏ธ Attenzione alla modalitร  rigorosa: In base a ONLY_FULL_GROUP_BY, ogni colonna selezionata deve essere raggruppata o racchiusa in una funzione di aggregazione.

Clausola SQL GROUP BY e HAVING

Cos'รจ la clausola GROUP BY di SQL?

La clausola GROUP BY รจ un comando SQL utilizzato per raggruppare le righe che hanno gli stessi valoriViene inserita all'interno dell'istruzione SELECT e viene normalmente utilizzata insieme alle funzioni di aggregazione per generare report riepilogativi dal database.

Ecco cosa fa: riassume i dati conservati nel database. Le query che contengono la clausola GROUP BY sono chiamate query raggruppate e restituiscono una singola riga per ogni elemento raggruppato.

Sintassi SQL GROUP BY

Ora che lo scopo della clausola รจ chiaro, esaminiamo la sintassi di una query raggruppata di base.

SELECT statements... GROUP BY column_name1[, column_name2, ...] [HAVING condition];

QUI

  • "Istruzioni SELECTโ€ฆ" รจ lo standard SELEZIONA SQL query del comando.
  • "RAGGRUPPA PER nome_colonna1" รจ la clausola che esegue il gruppoping in base al nome della colonna1.
  • "[, nome_colonna2, โ€ฆ]" รจ facoltativo e rappresenta altri nomi di colonna quando il gruppoping viene fatto su piรน di una colonna.
  • "[Condizione di avere]" รจ facoltativo e viene utilizzato per limitare le righe interessate dalla clausola GROUP BY. รˆ simile a Dove la clausola, tranne che viene applicato dopo il gruppoping.

Grouping Utilizzando una singola colonna

Il modo piรน rapido per vedere l'effetto della clausola SQL GROUP BY รจ confrontare una query non raggruppata con una raggruppata. Inizia con una query semplice che restituisce ogni voce relativa al genere nella tabella dei membri.

SELECT `gender` FROM `members`;
genere
Femmina
Femmina
Maschio
Femmina
Maschio
Maschio
Maschio
Maschio
Maschio

Vengono restituite nove righe e ogni valore viene ripetuto. Supponiamo di volere invece i valori univoci per il genere. La query seguente aggiunge la clausola GROUP BY.

SELECT `gender` FROM `members` GROUP BY `gender`;

Eseguendo lo script precedente in MySQL banco di lavoro rispetto a myflixdb ci fornisce i seguenti risultati.

genere
Femmina
Maschio

Si noti che sono state restituite solo due righe, perchรฉ la tabella contiene solo due tipi di genere. La clausola GROUP BY ha raggruppato tutti i membri "Maschio" e ha restituito una singola riga per essi, e ha fatto lo stesso con i membri "Femmina".

Grouping Utilizzo di piรน colonne

Grouping Un'analisi basata su una sola colonna รจ spesso troppo generica per un report reale. La clausola GROUP BY accetta un elenco di colonne separate da virgole e la combinazione dei loro valori definisce ciascun gruppo.

Supponiamo di voler ottenere un elenco di valori category_id per i film e i corrispondenti anni di uscita. Osserviamo innanzitutto l'output di questa semplice query.

SELECT `category_id`, `year_released` FROM `movies`;
categoria_id anno_rilasciato
1 2011
2 2008
NULL 2008
NULL 2010
8 2007
6 2007
6 2007
8 2005
NULL 2012
7 1920
8 NULL
8 1920

Le righe evidenziate mostrano che il risultato contiene duplicati. Eseguendo la stessa query con GROUP BY, questi vengono rimossi.

SELECT `category_id`, `year_released` FROM `movies` GROUP BY `category_id`, `year_released`;

Eseguendo lo script precedente in MySQL L'analisi con Workbench su myflixdb fornisce i seguenti risultati, mostrati di seguito.

categoria_id anno_rilasciato
NULL 2008
NULL 2010
NULL 2012
1 2011
2 2008
6 2007
7 1920
8 1920
8 2005
8 2007

La clausola GROUP BY opera sia su category_id che su year_released per identificare unica righe. Le due righe duplicate per la categoria 6 nel 2007 sono state accorpate in una sola.

Regola del pollice: Se l'ID della categoria รจ lo stesso ma l'anno di pubblicazione รจ diverso, la riga viene considerata univoca. Se l'ID della categoria e l'anno di pubblicazione sono uguali per piรน di una riga, le righe sono duplicate e ne viene visualizzata solo una.

Grouping e funzioni aggregate

Rimuovere i duplicati รจ utile, ma il vero potere del raggruppamentoping appare quando รจ abbinato a funzioni aggregate. Una funzione di aggregazione calcola un valore per ogni gruppo: COUNT conta le righe, SUM somma i valori e AVG, MIN e MAX descrivono la dispersione.

Supponiamo di voler ottenere il numero totale di membri maschi e femmine presenti nel database. Lo script seguente esegue questa operazione.

SELECT `gender`, COUNT(`membership_number`) FROM `members` GROUP BY `gender`;

Eseguendo lo script precedente in MySQL L'analisi con Workbench su myflixdb ci fornisce i seguenti risultati.

genere CONTA(`numero_di_iscrizione`)
Femmina 3
Maschio 6

Le righe sono raggruppate in base a ciascun valore univoco del genere e il numero di righe all'interno di ciascun gruppo viene conteggiato dalla funzione di aggregazione COUNT. I nove record dei membri vengono poi raggruppati in due righe di riepilogo.

Limitare i risultati delle query utilizzando la clausola HAVING

GroupingNon sempre si desidera ottenere risultati per ogni riga di una tabella. Talvolta il report deve essere limitato a un determinato criterio, ed รจ questo il compito della clausola HAVING.

Supponiamo di voler conoscere tutti gli anni di uscita per la categoria di film con ID 8. Lo script seguente permette di ottenere questo risultato.

SELECT * FROM `movies` GROUP BY `category_id`, `year_released` HAVING `category_id` = 8;

Eseguendo lo script precedente in MySQL L'analisi con Workbench su myflixdb fornisce i seguenti risultati, mostrati di seguito.

id_film titolo direttore anno_rilasciato categoria_id
9 Honey moonERS John Schutz 2005 8
5 Le bambine di papร  NULL 2007 8

Solo i film con ID categoria 8 sono stati mantenuti dalla condizione HAVING.

Attenzione: MySQL 5.7 e versioni successive abilitano la modalitร  ONLY_FULL_GROUP_BY per impostazione predefinita e, in tale modalitร , SELECT * con una clausola GROUP BY viene rifiutata, perchรฉ movie_id, title e director non sono nรฉ raggruppati nรฉ aggregati. In produzione, denominare esplicitamente le colonne raggruppate, ad esempio SELEZIONA category_id, year_released DA movies GRUPPO PER category_id, year_released AVENDO category_id = 8;

DOVE vs AVERE vs GRUPPO PER vs ORDINA PER

I principianti spesso confondono queste quattro clausole, perchรฉ tutte plasmano l'insieme dei risultati. La differenza sta in quando MySQL Le seguenti clausole vengono applicate: WHERE viene eseguita prima del raggruppamento delle righe, HAVING viene eseguita dopo e ORDER BY viene eseguita per ultima.

Clausola Ciรฒ che fa Quando funziona Accetta funzioni aggregate
DOVE Filtra le singole righe prima di qualsiasi gruppoping. Prima di raggruppare per Non
RAGGRUPPA PER Raggruppa le righe che condividono gli stessi valori in un'unica riga per gruppo. Dopo DOVE Non applicabile
VISTA Filtra i gruppi prodotti da GROUP BY. Dopo il raggruppamento per Sรฌ, ad esempio HAVING COUNT(*) > 2
ORDINATO DA Ordina le righe che sopravvivono alle clausole precedenti. Cognome Sรฌ, un alias aggregato puรฒ essere ordinato

La conseguenza pratica รจ di natura prestazionale. Il filtraggio con WHERE rimuove le righe prima del gruppoping Il lavoro inizia, quindi una condizione che non dipende da un risultato aggregato va inserita in WHERE piuttosto che in HAVING.

DOMANDE FREQUENTI

Sรฌ. GROUP BY da solo restituisce una riga per ogni valore univoco, eliminando i duplicati in modo molto simile a SELECT DISTINCT. Le funzioni di aggregazione sono necessarie solo quando a ciascun gruppo serve un valore calcolato.

L'errore si verifica quando una colonna selezionata non รจ presente nell'elenco GROUP BY nรฉ รจ racchiusa in una funzione di aggregazione. MySQL Non riesce a decidere quale valore di quella colonna mostrare per il gruppo, quindi rifiuta la query.

COUNT(*) conta ogni riga nel gruppo. COUNT(colonna) conta solo le righe in cui quella colonna non รจ NULL, quindi le due cifre differiscono ogni volta che la colonna contiene valori mancanti.

Sรฌ. Gli assistenti IA all'interno di strumenti come MySQL banco di lavoro tradurre una richiesta come "membri per genere" in una query raggruppata. Controllare il gruppoping colonne voi stessi, perchรฉ un gruppo sbagliatoping produce totali che sembrano plausibili ma sono errati.

Spesso sรฌ. Gli assistenti di query basati sull'IA segnalano cause classiche come una ISCRIVITI che moltiplica le righe prima del gruppopingoppure un filtro inserito in HAVING invece che in WHERE. La decisione finale spetta comunque a chi conosce i dati.

Riassumi questo post con: