Sqlserver
 sql >> Database >  >> RDS >> Sqlserver

Presentazione delle espressioni di tabella comuni in SQL Server

Common Table Expressions, o CTE in breve, è semplicemente una tecnica per creare un insieme temporaneo di record a cui è possibile fare riferimento all'interno di un'istruzione INSERT, SELECT, UPDATE o DELETE.

Le espressioni di tabella comuni sono state introdotte da Microsoft in SQL Server 2005. Non vengono archiviate come oggetti nella memoria del database poiché la loro durata è uguale al tempo di esecuzione della query. Non appena una query viene completata, vengono rimossi dalla memoria del database. CTE può essere referenziato in una query tutte le volte che vuoi e possono anche essere autoreferenziali.

Creiamo un database con una tabella studenti e inseriamo in essa alcuni record di studenti fittizi. Useremo questo database per scrivere query CTE. Come sempre, assicurati di aver eseguito un backup corretto prima di sperimentare un nuovo codice. Se non sei sicuro, consulta questo articolo sul backup SQL.

Esegui le seguenti query sul tuo server.

CREATE DATABASE schooldb

CREATE TABLE student
(
    id INT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    gender VARCHAR(50) NOT NULL,
    DOB datetime NOT NULL,
    total_score INT NOT NULL,
    
 )

INSERT INTO student

VALUES (1, 'Jolly', 'Female', '12-JUN-1989', 500), 
(2, 'Jon', 'Male', '02-FEB-1974', 545), 
(3, 'Sara', 'Female', '07-MAR-1988', 600), 
(4, 'Laura', 'Female', '22-DEC-1981', 400), 
(5, 'Alan', 'Male', '29-JUL-1993', 500), 
(6, 'Kate', 'Female', '03-JAN-1985', 500), 
(7, 'Joseph', 'Male', '09-APR-1982', 643), 
(8, 'Mice', 'Male', '16-AUG-1974', 543), 
(9, 'Wise', 'Male', '11-NOV-1987', 499), 
(10, 'Elis', 'Female', '28-OCT-1990', 400);

Ora creiamo un'espressione di tabella comune molto semplice. Questo CTE conterrà i record di tutti gli studenti nati prima del 1 gennaio 1985. Dai un'occhiata al seguente script.

USE schooldb;

WITH OldStudents AS
(
SELECT * FROM student
WHERE DOB < '1985-01-01'
)

Per creare un CTE, devi iniziare con la parola chiave "WITH" seguita dal nome del CTE e dalla parola chiave "AS".

Successivamente, tra parentesi, devi scrivere la query che restituisce i record che il CTE memorizzerà temporaneamente. Nello script precedente, abbiamo creato un CTE denominato "OldStudents".

Tuttavia, tieni presente che se provi a eseguire la query precedente, riceverai un errore. Questo perché una volta creato un CTE, devi usarlo immediatamente.

Selezioniamo tutti i record dal nostro CTE "OldStudents" appena creato. Prova il seguente script sul tuo server.

USE schooldb;

WITH OldStudents AS
(
	SELECT * FROM student
	WHERE DOB < '1985-01-01'

)

SELECT * FROM OldStudents

Lo script precedente recupererà il seguente set di record:

Calcolo dell'aggregato tramite CTE

Come le tabelle, puoi eseguire funzioni aggregate su CTE. Diamo un'occhiata a un altro esempio di CTE.

USE schooldb;

WITH SumofScores AS
(
	SELECT 
		gender, SUM(total_score) as SumScore
	FROM student
	GROUP BY gender
)

SELECT AVG (SumScore)
FROM SumofScores

Nell'esempio sopra, abbiamo creato un CTE chiamato SumofScores. Questo CTE contiene la somma dei valori memorizzati nella colonna total_score della tabella studenti. Il risultato è raggruppato per la colonna del sesso. I dati memorizzati dal CTE si presentano così in memoria:

Successivamente, abbiamo eseguito la funzione AVG sulla colonna "SumScore" del CTE. Il risultato finale dello script sarà la media di 2400 e 2730 ovvero 2565.

Questo è un po' più complicato rispetto all'esempio precedente, ma mostra più chiaramente il concetto di CTE.

Etichettatura delle colonne in CTE

Nell'esempio precedente, abbiamo aggiunto un alias alla seconda colonna del CTE. Lo abbiamo rinominato come "SumScore". Questo è un modo per etichettare le colonne in CTE ed è simile agli alias delle colonne delle tabelle.

Tuttavia, esiste un altro modo per definire i nomi delle colonne in CTE. Dai un'occhiata alla seguente query.

USE schooldb;

WITH SumofScores(Gender, SumScore) AS
(
	SELECT 
		gender, SUM(total_score)
	FROM student
	GROUP BY gender
)

SELECT AVG (SumScore)
From SumofScores

In questo script, abbiamo aggiunto i nomi delle colonne del CTE "SumofScores" tra parentesi dopo il nome del CTE. Ogni nome di colonna è separato da una virgola.

Se guardi l'istruzione SELECT dopo il CTE, puoi vedere che stiamo facendo riferimento alla colonna "SumScore" che abbiamo creato tra parentesi dopo il nome CTE.

Creazione di più CTE

Tutti gli esempi finora hanno utilizzato solo un'unica espressione di tabella comune per chiarezza. Puoi creare un elenco di CTE contemporaneamente e quindi utilizzarli tutti in combinazione nel set di risultati finale.

Questo è meglio spiegato con l'aiuto di un esempio. Dai un'occhiata al seguente script di seguito.

Qui creeremo due CTE. Il primo CTE conterrà tutti i record degli studenti nati prima del 1 gennaio 1985. Il secondo CTE conterrà tutti i record degli studenti nati il ​​o dopo il 1 gennaio 1985.

Successivamente, utilizzeremo le istruzioni select per recuperare tutti i record da entrambi i CTE. I record recuperati verranno uniti insieme utilizzando l'istruzione UNION. Infine, il record unito verrà ordinato in ordine crescente di data di nascita.

USE schooldb;

WITH OldStudents AS
(
	SELECT * FROM student
	WHERE DOB < '1985-01-01'

),

YoungStudents AS
(
	SELECT * FROM student
	WHERE DOB >= '1985-01-01'

)

(SELECT * FROM OldStudents
UNION
SELECT * FROM YoungStudents)

ORDER BY DOB

Nella query SQL sopra, abbiamo creato due CTE:"OldStudents" e "YoungStudents". Vale la pena ricordare che non è necessario utilizzare la parola chiave "CON" con ogni CTE. Devi solo usarlo prima del primo CTE nello script, dopodiché puoi creare un numero qualsiasi di CTE separandoli con una virgola.

Lo script precedente recupera i seguenti risultati: