🧚 Ascolta! Beekeeper Studio è una GUI per database veloce, moderna e open source Scarica
7 gennaio 2026 Di Matthew Rathbone

Una tabella pivot trasforma le righe in colonne: una riga per gruppo e una colonna per ogni valore di un altro campo, ad esempio una colonna per trimestre. In SQL la costruisci con CASE dentro un'aggregazione come SUM, raggruppando per ciò che deve rappresentare ogni riga. Gli esempi funzionano in PostgreSQL, MySQL, SQLite e SQL Server.

Come creare una tabella pivot in SQL

Scrivi un'aggregazione per ogni colonna di output. Il CASE al suo interno fa passare solo le righe che appartengono a quella colonna, e GROUP BY restituisce una riga per gruppo:

SELECT
  row_column,
  SUM(CASE WHEN pivot_column = 'value 1' THEN amount ELSE 0 END) AS value_1,
  SUM(CASE WHEN pivot_column = 'value 2' THEN amount ELSE 0 END) AS value_2
FROM table_name
GROUP BY row_column;

Qui ogni prodotto ha una riga, con le unità di ogni trimestre affiancate:

-- Input: sales
-- product  | quarter | units
-- ---------+---------+------
-- Keyboard | Q1      | 120
-- Keyboard | Q2      | 95
-- Monitor  | Q1      | 40
-- Monitor  | Q2      | 55
-- Mouse    | Q2      | 210

SELECT
  product,
  SUM(CASE WHEN quarter = 'Q1' THEN units ELSE 0 END) AS q1,
  SUM(CASE WHEN quarter = 'Q2' THEN units ELSE 0 END) AS q2
FROM sales
GROUP BY product
ORDER BY product;

-- Output:
-- product  | q1  | q2
-- ---------+-----+----
-- Keyboard | 120 | 95
-- Monitor  | 40  | 55
-- Mouse    | 0   | 210

Regole da conoscere

  • Ogni colonna la nomini tu. SQL non può creare colonne a partire dai dati, quindi un terzo trimestre richiede una terza riga CASE. Se l'elenco dei valori cambia di continuo, costruisci la query nel codice della tua applicazione.
  • ELSE 0 serve solo per SUM e i conteggi. Trasforma una combinazione mancante in 0 invece di NULL. Con AVG, MIN o MAX, ometti ELSE, altrimenti gli zeri vengono considerati valori reali:
-- Input: the sales table above

SELECT
  product,
  ROUND(AVG(CASE WHEN quarter = 'Q1' THEN units ELSE 0 END), 1) AS q1_else_0,
  ROUND(AVG(CASE WHEN quarter = 'Q1' THEN units END), 1) AS q1_no_else
FROM sales
GROUP BY product
ORDER BY product;

-- Output:
-- product  | q1_else_0 | q1_no_else
-- ---------+-----------+-----------
-- Keyboard | 60.0      | 120.0
-- Monitor  | 20.0      | 40.0
-- Mouse    | 0.0       | NULL

Sintassi alternativa

Incontrerai anche FILTER in PostgreSQL e SQLite, e l'operatore PIVOT in SQL Server. Entrambi lasciano una combinazione mancante come NULL anziché 0:

-- Input: the sales table above

-- PostgreSQL and SQLite
SELECT
  product,
  SUM(units) FILTER (WHERE quarter = 'Q1') AS q1,
  SUM(units) FILTER (WHERE quarter = 'Q2') AS q2
FROM sales
GROUP BY product
ORDER BY product;

-- SQL Server
SELECT product, [Q1] AS q1, [Q2] AS q2
FROM (SELECT product, quarter, units FROM sales) AS src
PIVOT (SUM(units) FOR quarter IN ([Q1], [Q2])) AS p
ORDER BY product;

-- Output:
-- product  | q1   | q2
-- ---------+------+----
-- Keyboard | 120  | 95
-- Monitor  | 40   | 55
-- Mouse    | NULL | 210

Nel codice MySQL vedrai spesso SUM(IF(quarter = 'Q1', units, 0)), un modo più breve di scrivere la versione con CASE. L'estensione tablefunc di PostgreSQL offre anche la funzione crosstab(); vedi creare tabelle pivot in PostgreSQL con crosstab().

Quando conviene usare una tabella pivot?

Usa il pivot quando un elenco di righe sarebbe più leggibile come griglia. Questi sono i motivi più comuni.

Confrontare una misura fianco a fianco

Metti i valori da confrontare (giorni, trimestri, regioni) uno accanto all'altro in una riga, invece che sparsi in un lungo elenco.

Mostrare più misure per ogni colonna

Ogni colonna di output è un'aggregazione a sé, quindi puoi abbinarle: sessioni e visualizzazioni di pagina per dispositivo, oppure ordini e fatturato per canale.

Contare le righe per categoria

Per contare invece di sommare, somma 1 per ogni riga corrispondente, oppure usa COUNT(CASE WHEN ... THEN 1 END): COUNT ignora i NULL prodotti dalle altre righe. Così ottieni le attività per stato o i ticket per priorità.

Trasformare righe chiave-valore in colonne

Impostazioni e attributi dei prodotti sono spesso salvati come una riga per nome e valore. Il pivot con MAX(CASE ...) restituisce una riga per elemento con una colonna per attributo. MAX funziona sul testo e prende l'unico valore di ogni gruppo.

Esempi reali di tabelle pivot in SQL

Valutazione media delle app per piattaforma

Ometti ELSE quando calcoli una media, così un'app senza recensioni su una piattaforma mostra NULL invece di un punteggio fuorviante:

-- Input: reviews
-- app      | platform | rating
-- ---------+----------+-------
-- Budgetly | iOS      | 5
-- Budgetly | iOS      | 4
-- Budgetly | Android  | 3
-- FitTrack | Android  | 4
-- FitTrack | Android  | 5

-- In SQL Server, AVG of an integer column drops the decimals: use rating * 1.0
SELECT
  app,
  ROUND(AVG(CASE WHEN platform = 'iOS' THEN rating END), 1) AS ios,
  ROUND(AVG(CASE WHEN platform = 'Android' THEN rating END), 1) AS android
FROM reviews
GROUP BY app
ORDER BY app;

-- Output:
-- app      | ios  | android
-- ---------+------+--------
-- Budgetly | 4.5  | 3.0
-- FitTrack | NULL | 4.5

Ordini e vendite per canale in ogni regione

Due misure per ogni canale, il numero di ordini e un totale:

-- Input: orders
-- id | region | channel | amount
-- ---+--------+---------+-------
-- 1  | North  | web     | 120.00
-- 2  | North  | store   | 80.00
-- 3  | North  | web     | 45.50
-- 4  | South  | store   | 210.00
-- 5  | South  | store   | 64.00

SELECT
  region,
  COUNT(CASE WHEN channel = 'web' THEN 1 END) AS web_orders,
  SUM(CASE WHEN channel = 'web' THEN amount ELSE 0 END) AS web_sales,
  COUNT(CASE WHEN channel = 'store' THEN 1 END) AS store_orders,
  SUM(CASE WHEN channel = 'store' THEN amount ELSE 0 END) AS store_sales
FROM orders
GROUP BY region
ORDER BY region;

-- Output:
-- region | web_orders | web_sales | store_orders | store_sales
-- -------+------------+-----------+--------------+------------
-- North  | 2          | 165.50    | 1            | 80.00
-- South  | 0          | 0         | 2            | 274.00

Ticket di supporto per operatore e priorità

Un conteggio per ogni priorità, più un totale. COUNT(*) conta comunque tutte le righe del gruppo:

-- Input: tickets
-- id | agent | priority
-- ---+-------+---------
-- 1  | Priya | urgent
-- 2  | Priya | normal
-- 3  | Marco | normal
-- 4  | Priya | normal
-- 5  | Marco | low

SELECT
  agent,
  COUNT(CASE WHEN priority = 'low' THEN 1 END) AS low,
  COUNT(CASE WHEN priority = 'normal' THEN 1 END) AS normal,
  COUNT(CASE WHEN priority = 'urgent' THEN 1 END) AS urgent,
  COUNT(*) AS total
FROM tickets
GROUP BY agent
ORDER BY agent;

-- Output:
-- agent | low | normal | urgent | total
-- ------+-----+--------+--------+------
-- Marco | 1   | 1      | 0      | 2
-- Priya | 0   | 2      | 1      | 3

Una riga di impostazioni per utente

Ogni impostazione è salvata come nome e valore. Un utente che non l'ha mai impostata ottiene NULL in quella colonna:

-- Input: user_settings
-- user_id | setting  | value
-- --------+----------+--------------
-- 1       | theme    | dark
-- 1       | language | en
-- 2       | language | de
-- 2       | timezone | Europe/Berlin
-- 3       | theme    | light

SELECT
  user_id,
  MAX(CASE WHEN setting = 'theme' THEN value END) AS theme,
  MAX(CASE WHEN setting = 'language' THEN value END) AS language,
  MAX(CASE WHEN setting = 'timezone' THEN value END) AS timezone
FROM user_settings
GROUP BY user_id
ORDER BY user_id;

-- Output:
-- user_id | theme | language | timezone
-- --------+-------+----------+--------------
-- 1       | dark  | en       | NULL
-- 2       | NULL  | de       | Europe/Berlin
-- 3       | light | NULL     | NULL

Approfondimenti sulle tabelle pivot

Su questo blog:

Documentazione ufficiale:

Beekeeper Studio è una GUI per database gratuita & open source

Il miglior strumento per query & editor SQL che abbia mai usato. Offre tutto ciò che mi serve per gestire il mio database. - ⭐⭐⭐⭐⭐ Mit

Beekeeper Studio è veloce, intuitivo e facile da usare. Beekeeper supporta tantissimi database e funziona alla grande su Windows, Mac e Linux.

La versione Linux di Beekeeper è completa al 100%, senza tagli e senza compromessi sulle funzionalità.

Cosa dicono gli utenti di Beekeeper Studio

★★★★★
"Beekeeper Studio ha completamente sostituito il mio vecchio flusso di lavoro SQL. È veloce, intuitivo e rende di nuovo piacevole lavorare con i database."
— Alex K., Database Developer
★★★★★
"Ho provato tante GUI per database, ma Beekeeper trova l'equilibrio perfetto tra funzionalità e semplicità. Funziona e basta."
— Sarah M., Full Stack Engineer

Pronto a migliorare il tuo flusso di lavoro SQL?

download Scarica gratis