Nell’analisi dei dati o nella creazione di report tramite SQL, spesso è necessario ottenere il primo o l’ultimo valore di un insieme di dati. Per semplificare questo processo, le funzioni FIRST_VALUE e LAST_VALUE risultano molto utili. In questo articolo, spiegheremo come utilizzare queste funzioni per manipolare i dati in modo efficiente, fornendo esempi concreti.
Utilizzo base della funzione FIRST_VALUE
La funzione FIRST_VALUE viene utilizzata per ottenere il primo valore all’interno di una finestra o partizione specificata. Ciò consente di estrarre facilmente il valore della prima riga di un set di dati.
Sintassi di base
SELECT
column1,
FIRST_VALUE(column1) OVER (PARTITION BY column2 ORDER BY column3) AS first_value
FROM
table_name;
In questo esempio, i dati vengono partizionati in base a column2
e ordinati secondo column3
, per poi restituire il primo valore di column1
.
Esempio di utilizzo
Ad esempio, se si desidera ottenere il nome del primo dipendente assunto in ogni reparto da un database aziendale, si può utilizzare la seguente query.
SELECT
department,
employee_name,
FIRST_VALUE(employee_name) OVER (PARTITION BY department ORDER BY hire_date) AS first_hired
FROM
employees;
Questa query restituisce il nome del primo dipendente assunto in ogni reparto.
Esempi avanzati di utilizzo della funzione FIRST_VALUE
Oltre all’uso base, la funzione FIRST_VALUE è utile anche per query e analisi più complesse. Qui di seguito forniamo esempi pratici su dataset reali.
Ottenere la data della prima vendita da un dataset di vendite
Ad esempio, se si desidera ottenere la data della prima vendita per ogni prodotto in ciascun negozio, si può utilizzare la seguente query.
SELECT
store_id,
product_id,
sale_date,
FIRST_VALUE(sale_date) OVER (PARTITION BY store_id, product_id ORDER BY sale_date) AS first_sale_date
FROM
sales;
Questa query restituisce la data della prima vendita di ogni prodotto in ciascun negozio.
Ottenere il risultato del primo esame da un dataset di voti degli studenti
Se si desidera gestire i dati dei voti degli studenti, è possibile ottenere il risultato del primo esame di ciascuno studente.
SELECT
student_id,
exam_date,
score,
FIRST_VALUE(score) OVER (PARTITION BY student_id ORDER BY exam_date) AS first_exam_score
FROM
exam_results;
Questa query restituisce il punteggio del primo esame di ciascuno studente.
Ottenere l’importo del primo acquisto dai dati delle transazioni
Un esempio tratto dai dati delle transazioni dei clienti mostra come ottenere l’importo del primo acquisto per ciascun cliente.
SELECT
customer_id,
transaction_date,
amount,
FIRST_VALUE(amount) OVER (PARTITION BY customer_id ORDER BY transaction_date) AS first_purchase_amount
FROM
transactions;
Questa query restituisce l’importo del primo acquisto di ciascun cliente.
Utilizzo base della funzione LAST_VALUE
La funzione LAST_VALUE viene utilizzata per ottenere l’ultimo valore all’interno di una finestra o partizione specificata. Ciò consente di estrarre facilmente il valore dell’ultima riga di un set di dati.
Sintassi di base
SELECT
column1,
LAST_VALUE(column1) OVER (PARTITION BY column2 ORDER BY column3 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_value
FROM
table_name;
In questo esempio, i dati vengono partizionati in base a column2
e ordinati secondo column3
, per poi restituire l’ultimo valore di column1
. È importante specificare l’intera finestra con la clausola ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
.
Esempio di utilizzo
Ad esempio, se si desidera ottenere il nome dell’ultimo dipendente assunto in ogni reparto da un database aziendale, si può utilizzare la seguente query.
SELECT
department,
employee_name,
LAST_VALUE(employee_name) OVER (PARTITION BY department ORDER BY hire_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_hired
FROM
employees;
Questa query restituisce il nome dell’ultimo dipendente assunto in ciascun reparto.
Esempi avanzati di utilizzo della funzione LAST_VALUE
Come la funzione FIRST_VALUE, anche LAST_VALUE è molto utile nell’analisi dei dati e nella creazione di report. Qui di seguito forniamo esempi pratici utilizzando dataset reali.
Ottenere la data dell’ultima vendita da un dataset di vendite
Ad esempio, se si desidera ottenere la data dell’ultima vendita per ogni prodotto in ciascun negozio, si può utilizzare la seguente query.
SELECT
store_id,
product_id,
sale_date,
LAST_VALUE(sale_date) OVER (PARTITION BY store_id, product_id ORDER BY sale_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_sale_date
FROM
sales;
Questa query restituisce la data dell’ultima vendita di ogni prodotto in ciascun negozio.
Ottenere il risultato dell’ultimo esame da un dataset di voti degli studenti
Se si desidera gestire i dati dei voti degli studenti, è possibile ottenere il risultato dell’ultimo esame di ciascuno studente.
SELECT
student_id,
exam_date,
score,
LAST_VALUE(score) OVER (PARTITION BY student_id ORDER BY exam_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_exam_score
FROM
exam_results;
Questa query restituisce il punteggio dell’ultimo esame di ciascuno studente.
Ottenere l’importo dell’ultimo acquisto dai dati delle transazioni
Un esempio tratto dai dati delle transazioni dei clienti mostra come ottenere l’importo dell’ultimo acquisto per ciascun cliente.
SELECT
customer_id,
transaction_date,
amount,
LAST_VALUE(amount) OVER (PARTITION BY customer_id ORDER BY transaction_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_purchase_amount
FROM
transactions;
Questa query restituisce l’importo dell’ultimo acquisto di ciascun cliente.
Combinare FIRST_VALUE e LAST_VALUE
Combinando le funzioni FIRST_VALUE e LAST_VALUE, è possibile ottenere contemporaneamente il primo e l’ultimo valore di un set di dati. Questo permette di effettuare analisi avanzate, come il confronto tra il primo e l’ultimo valore di un intervallo temporale.
Ottenere la prima e l’ultima data di vendita da un dataset di vendite
Ad esempio, la seguente query restituisce la prima e l’ultima data di vendita per ciascun prodotto in ogni negozio.
SELECT
store_id,
product_id,
FIRST_VALUE(sale_date) OVER (PARTITION BY store_id, product_id ORDER BY sale_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS first_sale_date,
LAST_VALUE(sale_date) OVER (PARTITION BY store_id, product_id ORDER BY sale_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_sale_date
FROM
sales;
Questa query restituisce la prima e l’ultima data di vendita per ciascun prodotto in ogni negozio.
Ottenere la prima e l’ultima data di assunzione dei dipendenti
Per ottenere la prima e l’ultima data di assunzione di ciascun dipartimento nel database dei dipendenti, si può utilizzare la seguente query.
SELECT
department,
employee_name,
FIRST_VALUE(hire_date) OVER (PARTITION BY department ORDER BY hire_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS first_hire_date,
LAST_VALUE(hire_date) OVER (PARTITION BY department ORDER BY hire_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_hire_date
FROM
employees;
Questa query restituisce il nome del dipendente assunto per primo e per ultimo in ciascun reparto.
Ottenere il primo e l’ultimo importo di acquisto dai dati delle transazioni
La seguente query mostra come ottenere il primo e l’ultimo importo di acquisto di ciascun cliente dai dati delle transazioni.
SELECT
customer_id,
FIRST_VALUE(amount) OVER (PARTITION BY customer_id ORDER BY transaction_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS first_purchase_amount,
LAST_VALUE(amount) OVER (PARTITION BY customer_id ORDER BY transaction_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_purchase_amount
FROM
transactions;
Questa query restituisce il primo e l’ultimo importo di acquisto di ciascun cliente.
Utilizzo come funzioni di finestra
Le funzioni FIRST_VALUE e LAST_VALUE possono essere utilizzate come funzioni di finestra, il che consente di analizzare e manipolare i dati in modo più flessibile. Come funzioni di finestra, calcolano i valori di ogni riga e li restituiscono come risultati.
Concetto di base delle funzioni di finestra
Le funzioni di finestra eseguono calcoli sui set di risultati di una query e si applicano a specifiche finestre di righe. Le finestre sono definite utilizzando le clausole PARTITION BY e ORDER BY.
Sintassi di base
SELECT
column1,
FIRST_VALUE(column1) OVER (PARTITION BY column2 ORDER BY column3 ROWS
BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS first_value,
LAST_VALUE(column1) OVER (PARTITION BY column2 ORDER BY column3 ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_value
FROM
table_name;
In questa sintassi, i dati vengono partizionati in base a column2
e ordinati secondo column3
, per poi restituire il primo e l’ultimo valore di column1
.
Esempio di utilizzo: Funzione di finestra sui dati di vendita
Ad esempio, per ottenere la prima e l’ultima data di vendita nei dati di vendita di ciascun negozio, si può utilizzare la seguente query.
SELECT
store_id,
product_id,
sale_date,
FIRST_VALUE(sale_date) OVER (PARTITION BY store_id ORDER BY sale_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS first_sale_date,
LAST_VALUE(sale_date) OVER (PARTITION BY store_id ORDER BY sale_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_sale_date
FROM
sales;
Questa query restituisce la prima e l’ultima data di vendita di ciascun negozio.
Esempio di utilizzo: Dati degli studenti
Se si desidera ottenere il primo e l’ultimo punteggio di ciascun studente nel proprio dataset, si può utilizzare la seguente query.
SELECT
student_id,
exam_date,
score,
FIRST_VALUE(score) OVER (PARTITION BY student_id ORDER BY exam_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS first_exam_score,
LAST_VALUE(score) OVER (PARTITION BY student_id ORDER BY exam_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_exam_score
FROM
exam_results;
Questa query restituisce il primo e l’ultimo punteggio d’esame di ciascun studente.
Partizionamento e utilizzo di ORDER BY
Una delle caratteristiche potenti delle funzioni FIRST_VALUE e LAST_VALUE è la capacità di partizionare e ordinare i dati. Questo permette di ottenere il primo e l’ultimo valore all’interno di gruppi specifici.
Concetto base del partizionamento
Il partizionamento suddivide i dati in gruppi specifici, consentendo di eseguire calcoli indipendenti per ciascun gruppo. La clausola PARTITION BY viene utilizzata per definire i partizionamenti.
Concetto base dell’ORDER BY
La clausola ORDER BY viene utilizzata per ordinare le righe all’interno di ciascuna partizione. Questo consente di identificare con precisione i primi e gli ultimi valori.
Esempio di utilizzo di partizionamento e ORDER BY
La seguente query mostra come ottenere la prima e l’ultima data di vendita per ciascun prodotto in ogni negozio utilizzando il partizionamento e l’ORDER BY.
SELECT
store_id,
product_id,
sale_date,
FIRST_VALUE(sale_date) OVER (PARTITION BY store_id, product_id ORDER BY sale_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS first_sale_date,
LAST_VALUE(sale_date) OVER (PARTITION BY store_id, product_id ORDER BY sale_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_sale_date
FROM
sales;
Questa query restituisce la prima e l’ultima data di vendita per ciascun prodotto in ogni negozio.
Esempio avanzato sui dati degli studenti
Per ottenere il primo e l’ultimo punteggio di ciascun studente dai dati di esame, si può utilizzare la seguente query.
SELECT
student_id,
exam_date,
score,
FIRST_VALUE(score) OVER (PARTITION BY student_id ORDER BY exam_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS first_exam_score,
LAST_VALUE(score) OVER (PARTITION BY student_id ORDER BY exam_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_exam_score
FROM
exam_results;
Questa query restituisce il primo e l’ultimo punteggio d’esame di ciascun studente.
Esempio avanzato sui dati delle transazioni
Per ottenere il primo e l’ultimo importo di acquisto di ciascun cliente dai dati delle transazioni, si può utilizzare la seguente query.
SELECT
customer_id,
transaction_date,
amount,
FIRST_VALUE(amount) OVER (PARTITION BY customer_id ORDER BY transaction_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS first_purchase_amount,
LAST_VALUE(amount) OVER (PARTITION BY customer_id ORDER BY transaction_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_purchase_amount
FROM
transactions;
Questa query restituisce il primo e l’ultimo importo di acquisto di ciascun cliente.
Esercizi pratici e soluzioni
Per consolidare quanto appreso sulle funzioni FIRST_VALUE e LAST_VALUE in questo articolo, abbiamo preparato alcuni esercizi pratici. Ogni esercizio include una soluzione, che potrete testare per verificare la vostra comprensione.
Esercizio 1: Ottenere la prima e l’ultima data di assunzione di ciascun reparto
Crea una query per ottenere la prima e l’ultima data di assunzione di ciascun reparto dalla tabella employees
.
-- employees table
+---------+------------+------------+
| emp_id | department | hire_date |
+---------+------------+------------+
| 1 | Sales | 2020-01-01 |
| 2 | Sales | 2021-05-10 |
| 3 | HR | 2019-03-15 |
| 4 | HR | 2020-07-23 |
| 5 | IT | 2021-01-05 |
+---------+------------+------------+
Soluzione
SELECT
department,
FIRST_VALUE(hire_date) OVER (PARTITION BY department ORDER BY hire_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS first_hire_date,
LAST_VALUE(hire_date) OVER (PARTITION BY department ORDER BY hire_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_hire_date
FROM
employees;
Esercizio 2: Ottenere la prima e l’ultima data di vendita di ciascun prodotto
Crea una query per ottenere la prima e l’ultima data di vendita di ciascun prodotto dalla tabella sales
.
-- sales table
+---------+------------+------------+
| sale_id | product_id | sale_date |
+---------+------------+------------+
| 1 | 101 | 2022-01-01 |
| 2 | 102 | 2022-01-05 |
| 3 | 101 | 2022-02-01 |
| 4 | 103 | 2022-01-10 |
| 5 | 102 | 2022-03-01 |
+---------+------------+------------+
Soluzione
SELECT
product_id,
FIRST_VALUE(sale_date) OVER (PARTITION BY product_id ORDER BY sale_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS first_sale_date,
LAST_VALUE(sale_date) OVER (PARTITION BY product_id ORDER BY sale_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_sale_date
FROM
sales;
Esercizio 3: Ottenere il primo e l’ultimo importo di acquisto di ciascun cliente
Crea una query per ottenere il primo e l’ultimo importo di acquisto di ciascun cliente dalla tabella transactions
.
-- transactions table
+-------------+----------+--------+--------------+
| transaction_id | customer_id | amount | transaction_date |
+-------------+----------+--------+--------------+
| 1 | 1001 | 200 | 2023-01-01 |
| 2 | 1002 | 150 | 2023-01-05 |
| 3 | 1001 | 300 | 2023-02-01 |
| 4 | 1003 | 250 | 2023-01-10 |
| 5 | 1002 | 400 | 2023-03-01 |
+-------------+----------+--------+--------------+
Soluzione
SELECT
customer_id,
FIRST_VALUE(amount) OVER (PARTITION BY customer_id ORDER BY transaction_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS first_purchase_amount,
LAST_VALUE(amount) OVER (PARTITION BY customer_id ORDER BY transaction_date ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS last_purchase_amount
FROM
transactions;
Conclusione
In questo articolo, abbiamo esplorato l’utilizzo delle funzioni SQL FIRST_VALUE e LAST_VALUE per ottenere il primo e l’ultimo valore di un dataset. Abbiamo trattato le basi, esempi avanzati, l’utilizzo come funzioni di finestra, nonché il partizionamento e l’ORDER BY. Utilizzando queste funzioni, l’analisi dei dati e la creazione di report diventano molto più efficienti. Vi invitiamo a provare queste tecniche su dataset reali.