sql >> Base de Datos >  >> RDS >> Sqlserver

Introducción a las expresiones de tabla comunes en SQL Server

Common Table Expressions, o CTE para abreviar, es simplemente una técnica para crear un conjunto temporal de registros a los que se puede hacer referencia dentro de una instrucción INSERT, SELECT, UPDATE o DELETE.

Microsoft introdujo expresiones de tabla comunes en SQL Server 2005. No se almacenan como objetos en la memoria de la base de datos ya que su vida útil es igual al tiempo de ejecución de la consulta. Tan pronto como se completa una consulta, se eliminan de la memoria de la base de datos. Se puede hacer referencia a CTE en una consulta tantas veces como quieras y también pueden ser autorreferenciales.

Vamos a crear una base de datos con una tabla de estudiantes e insertar algunos registros de estudiantes ficticios en ella. Usaremos esta base de datos para escribir consultas CTE. Como siempre, asegúrese de tener una buena copia de seguridad antes de experimentar con un nuevo código. Consulte este artículo sobre la copia de seguridad de SQL si no está seguro.

Ejecute las siguientes consultas en su servidor.

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);

Ahora, creemos una expresión de tabla común muy simple. Este CTE contendrá registros de todos los estudiantes que nacieron antes del 1 de enero de 1985. Eche un vistazo al siguiente guión.

USE schooldb;

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

Para crear un CTE, debe comenzar con la palabra clave "CON", seguida del nombre del CTE y la palabra clave "AS".

A continuación, dentro del paréntesis, hay que escribir la consulta que devuelve los registros que almacenará temporalmente el CTE. En el script anterior, creamos un CTE llamado "OldStudents".

Sin embargo, tenga en cuenta que si intenta ejecutar la consulta anterior, obtendrá un error. Esto se debe a que una vez que crea un CTE, debe usarlo inmediatamente.

Seleccionemos todos los registros de nuestro CTE "OldStudents" recién creado. Pruebe el siguiente script en su servidor.

USE schooldb;

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

)

SELECT * FROM OldStudents

El script anterior recuperará el siguiente conjunto de registros:

Cálculo de agregados a través de CTE

Al igual que las tablas, puede realizar funciones agregadas en CTE. Echemos un vistazo a otro ejemplo de CTE.

USE schooldb;

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

SELECT AVG (SumScore)
FROM SumofScores

En el ejemplo anterior, creamos un CTE llamado SumofScores. Este CTE contiene la suma de los valores almacenados en la columna total_score de la tabla de estudiantes. El resultado se agrupa por la columna de género. Los datos almacenados por el CTE se ven así en la memoria:

A continuación, realizamos la función AVG en la columna "SumScore" del CTE. El resultado final del script será la media de 2400 y 2730, es decir, 2565.

Esto es un poco más complicado que el ejemplo anterior pero demuestra el concepto de CTE más claramente.

Columnas de etiquetado en CTE

En el ejemplo anterior, agregamos un alias a la segunda columna del CTE. Lo renombramos como "SumScore". Esta es una forma de etiquetar columnas en CTE y es similar a los alias de columna de tabla.

Sin embargo, hay otra forma de definir los nombres de las columnas en CTE. Echa un vistazo a la siguiente consulta.

USE schooldb;

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

SELECT AVG (SumScore)
From SumofScores

En este script, agregamos los nombres de las columnas del CTE "SumofScores" entre paréntesis después del nombre del CTE. Cada nombre de columna está separado por una coma.

Si observa la declaración SELECT después del CTE, puede ver que estamos haciendo referencia a la columna "SumScore" que creamos entre paréntesis después del nombre del CTE.

Creación de múltiples CTE

Todos los ejemplos hasta ahora solo han usado una única expresión de tabla común para mayor claridad. Puede crear una lista de CTE al mismo tiempo y luego usarlos todos en combinación en el conjunto de resultados final.

Esto se explica mejor con la ayuda de un ejemplo. Eche un vistazo a la siguiente secuencia de comandos a continuación.

Aquí crearemos dos CTE. El primer CTE almacenará todos los registros de los estudiantes nacidos antes del 1 de enero de 1985. El segundo CTE contendrá todos los registros de los estudiantes nacidos a partir del 1 de enero de 1985.

Después de eso, usaremos declaraciones de selección para recuperar todos los registros de ambos CTE. Los registros recuperados se fusionarán mediante la instrucción UNION. Finalmente, el registro combinado se clasificará en orden ascendente de fecha de nacimiento.

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

En la consulta SQL anterior, creamos dos CTE:"OldStudents" y "YoungStudents". Vale la pena mencionar que no necesita usar la palabra clave "CON" con cada CTE. Solo debe usarlo antes del primer CTE en el script, después de eso puede crear cualquier número de CTE separándolos con una coma.

El script anterior recupera los siguientes resultados: