Ricerca…
introduzione
I risultati di una query SELECT possono essere raggruppati da una o più colonne utilizzando l'istruzione GROUP BY
: tutti i risultati con lo stesso valore nelle colonne raggruppate vengono aggregati insieme. Questo genera una tabella di risultati parziali, invece di un risultato. GROUP BY può essere utilizzato insieme alle funzioni di aggregazione utilizzando l'istruzione HAVING
per definire come aggregare le colonne non raggruppate.
Sintassi
RAGGRUPPA PER {
Colonna-espressione
| ROLLUP (<group_by_expression> [, ... n])
| CUBE (<group_by_expression> [, ... n])
| GRUPPI DI GRUPPO ([, ... n])
| () - calcola il totale generale
} [, ... n]<group_by_expression> :: =
Colonna-espressione
| (espressione della colonna [, ... n])<grouping_set> :: =
() - calcola il totale generale
| <Grouping_set_item>
| (<grouping_set_item> [, ... n])<grouping_set_item> :: =
<Group_by_expression>
| ROLLUP (<group_by_expression> [, ... n])
| CUBE (<group_by_expression> [, ... n])
USA GROUP BY per COUNT il numero di righe per ogni voce univoca in una determinata colonna
Supponiamo di voler generare conteggi o subtotali per un dato valore in una colonna.
Dato questo tavolo, "Westerosians":
Nome | GreatHouseAllegience |
---|---|
Arya | rigido |
cercei | Lannister |
Myrcella | Lannister |
yara | Greyjoy |
Catelyn | rigido |
Sansa | rigido |
Senza GROUP BY, COUNT restituirà semplicemente un numero totale di righe:
SELECT Count(*) Number_of_Westerosians
FROM Westerosians
ritorna...
Number_of_Westerosians |
---|
6 |
Ma aggiungendo GROUP BY, possiamo COUNT gli utenti per ogni valore in una determinata colonna, per restituire il numero di persone in una determinata Grande Casa, per esempio:
SELECT GreatHouseAllegience House, Count(*) Number_of_Westerosians
FROM Westerosians
GROUP BY GreatHouseAllegience
ritorna...
Casa | Number_of_Westerosians |
---|---|
rigido | 3 |
Greyjoy | 1 |
Lannister | 2 |
È comune combinare GROUP BY con ORDER BY per ordinare i risultati per categoria più grande o più piccola:
SELECT GreatHouseAllegience House, Count(*) Number_of_Westerosians
FROM Westerosians
GROUP BY GreatHouseAllegience
ORDER BY Number_of_Westerosians Desc
ritorna...
Casa | Number_of_Westerosians |
---|---|
rigido | 3 |
Lannister | 2 |
Greyjoy | 1 |
Filtra i risultati GROUP BY utilizzando una clausola HAVING
Una clausola HAVING filtra i risultati di un'espressione GROUP BY. Nota: i seguenti esempi utilizzano il database di esempio Library .
Esempi:
Restituisci tutti gli autori che hanno scritto più di un libro ( esempio dal vivo ).
SELECT
a.Id,
a.Name,
COUNT(*) BooksWritten
FROM BooksAuthors ba
INNER JOIN Authors a ON a.id = ba.authorid
GROUP BY
a.Id,
a.Name
HAVING COUNT(*) > 1 -- equals to HAVING BooksWritten > 1
;
Restituisci tutti i libri che hanno più di tre autori ( esempio dal vivo ).
SELECT
b.Id,
b.Title,
COUNT(*) NumberOfAuthors
FROM BooksAuthors ba
INNER JOIN Books b ON b.id = ba.bookid
GROUP BY
b.Id,
b.Title
HAVING COUNT(*) > 3 -- equals to HAVING NumberOfAuthors > 3
;
Esempio di base GROUP BY
Potrebbe essere più semplice se si pensa a GROUP BY come "per ciascuno" a scopo di spiegazione. La query qui sotto:
SELECT EmpID, SUM (MonthlySalary)
FROM Employee
GROUP BY EmpID
sta dicendo:
"Dammi la somma di MonthlySalary's per ogni EmpID"
Quindi se il tuo tavolo fosse così:
+-----+-------------+
|EmpID|MonthlySalary|
+-----+-------------+
|1 |200 |
+-----+-------------+
|2 |300 |
+-----+-------------+
Risultato:
+-+---+
|1|200|
+-+---+
|2|300|
+-+---+
Sum non sembra fare nulla perché la somma di un numero è quel numero. D'altra parte se sembra così:
+-----+-------------+
|EmpID|MonthlySalary|
+-----+-------------+
|1 |200 |
+-----+-------------+
|1 |300 |
+-----+-------------+
|2 |300 |
+-----+-------------+
Risultato:
+-+---+
|1|500|
+-+---+
|2|300|
+-+---+
Allora sarebbe perché ci sono due EmpID 1 da sommare insieme.
Aggregazione ROLAP (data mining)
Descrizione
Lo standard SQL fornisce due operatori aggregati aggiuntivi. Questi usano il valore polimorfico "ALL" per indicare l'insieme di tutti i valori che un attributo può assumere. I due operatori sono:
-
with data cube
che fornisce tutte le combinazioni possibili rispetto agli attributi argomento della clausola. -
with roll up
che fornisce gli aggregati ottenuti considerando gli attributi nell'ordine da sinistra a destra rispetto a come sono elencati nell'argomento della clausola.
Versioni standard SQL che supportano queste funzionalità: 1999,2003,2006,2008,2011.
Esempi
Considera questa tabella:
Cibo | Marca | Importo totale |
---|---|---|
Pasta | Brand1 | 100 |
Pasta | brand2 | 250 |
Pizza | brand2 | 300 |
Con il cubo
select Food,Brand,Total_amount
from Table
group by Food,Brand,Total_amount with cube
Cibo | Marca | Importo totale |
---|---|---|
Pasta | Brand1 | 100 |
Pasta | brand2 | 250 |
Pasta | TUTTI | 350 |
Pizza | brand2 | 300 |
Pizza | TUTTI | 300 |
TUTTI | Brand1 | 100 |
TUTTI | brand2 | 550 |
TUTTI | TUTTI | 650 |
Con roll up
select Food,Brand,Total_amount
from Table
group by Food,Brand,Total_amount with roll up
Cibo | Marca | Importo totale |
---|---|---|
Pasta | Brand1 | 100 |
Pasta | brand2 | 250 |
Pizza | brand2 | 300 |
Pasta | TUTTI | 350 |
Pizza | TUTTI | 300 |
TUTTI | TUTTI | 650 |