25th Jun 2024 Lectura de 9 minutos ¿Qué es una expresión común de tabla (CTE) en SQL? Ignacio L. Bisso SQL aprender SQL CTE Índice Las CTEs ayudan a simplificar las consultas Aprendizaje de las Expresiones Comunes de Tabla SQL mediante Ejemplos Uso de CTEs en Consultas SQL avanzado CTEs anidados en consultas SQL Consultas recursivas y expresiones de tabla comunes y Expresiones Comunes de Tabla Las CTE de SQL son un potente recurso La expresión común de tabla (CTE) es una potente construcción de SQL que ayuda a simplificar una consulta. Las CTEs funcionan como tablas virtuales (con registros y columnas), creadas durante la ejecución de una consulta, utilizadas por la consulta y eliminadas tras la ejecución de la consulta. Las CTE suelen actuar como puente para transformar los datos de las tablas de origen al formato esperado por la consulta. Pregunta: ¿Qué es una expresión común de tabla en SQL? Una Expresión de Tabla Común (CTE) es como una subconsulta con nombre. Funciona como una tabla virtual a la que sólo puede acceder su consulta principal. Las CTEs pueden ayudar a simplificar, acortar y organizar su código. Una expresión de tabla común, o CTE, es un conjunto de resultados temporal con nombre creado a partir de una sentencia SELECT sencilla que puede utilizarse en una sentencia SELECT posterior. Cada CTE de SQL es como una consulta con nombre, cuyo resultado se almacena en una tabla virtual (una CTE) a la que se hará referencia posteriormente en la consulta principal. La mejor manera de aprender las expresiones comunes de tabla es mediante la práctica. Recomiendo el curso interactivo de LearnSQL.esConsultas recursivas y expresiones de tabla comunes de . Contiene más de 100 ejercicios que enseñan las CTEs empezando por lo básico y progresando hasta temas avanzados como las expresiones comunes de tabla recursivas. Las CTEs ayudan a simplificar las consultas Comencemos con la sintaxis de una expresión común de tabla. WITH my_cte AS ( SELECT a,b,c FROM T1 ) SELECT a,c FROM my_cte WHERE .... El nombre de esta CTE es my_ctey la consulta CTE es SELECT a,b,c FROM T1. La CTE comienza con la palabra clave WITH, tras la cual se especifica el nombre de la CTE y, a continuación, el contenido de la consulta entre paréntesis. La consulta principal viene después del paréntesis de cierre y hace referencia al CTE. Aquí, la consulta principal (también conocida como consulta externa) es SELECT a,c FROM my_cte WHERE …. Hay muchos ejemplos básicos en este excelente artículo introductorio sobre las CTE. Otros artículos introductorios incluyen "Improving Query Readability with Common Table Expressions" y "When Should I Use a Common Table Expression (CTE)?" que explican las expresiones comunes de tabla. Aprendizaje de las Expresiones Comunes de Tabla SQL mediante Ejemplos En esta sección, presentamos algunos ejemplos de consultas SQL que utilizan expresiones comunes de tabla. Todos los ejemplos se basan en una base de datos de una cadena de tiendas de teléfonos móviles. La tabla salesque se muestra a continuación, tiene un registro por producto vendido: branchdateselleritemquantityunit_price Paris-12021-12-07CharlesHeadphones A2180 London-12021-12-06JohnCell Phone X22120 London-22021-12-07MaryHeadphones A1160 Paris-12021-12-07CharlesBattery Charger150 London-22021-12-07MaryCell Phone B2290 London-12021-12-07JohnHeadphones A0575 London-12021-12-07SeanCell Phone X12100 En el primer ejemplo, obtenemos un informe con los mismos registros de la tabla sales pero añadimos una columna adicional con el precio del artículo más caro vendido en la misma sucursal ese día. Para obtener el precio del artículo más caro, utilizamos una expresión de tabla común como la siguiente: WITH highest AS ( SELECT branch, date, MAX(unit_price) AS highest_price FROM sales GROUP BY branch, date ) SELECT sales.*, h.highest_price FROM sales JOIN highest h ON sales.branch = h.branch AND sales.date = h.date Esta consulta define un CTE SQL llamado highest cuyo resultado crea una tabla virtual. La tabla virtual tiene las columnas sucursal, fecha y highest_price, que contienen el nombre de la sucursal, la fecha y el precio unitario más alto vendido ese día en esa sucursal, respectivamente. A continuación, se ejecuta la consulta externa, que utiliza la highest tabla virtual como si fuera una tabla normal. Por último, unimos el resultado de la CTE highest con la tabla sales tabla. A continuación se muestra el resultado de la consulta completa: branchdateselleritemquantityunit_pricehighest_ price Paris-12021-12-07CharlesHeadphones A218080 London-12021-12-06JohnCell Phone X22120120 London-22021-12-07MaryHeadphones A116090 Paris-12021-12-07CharlesBattery Charger15080 London-22021-12-07MaryCell Phone B229090 London-12021-12-07JohnHeadphones A0575100 London-12021-12-07SeanCell Phone X12100100 En el siguiente ejemplo, generamos un informe con los mayores ingresos diarios por sucursal. WITH daily_revenue AS ( SELECT branch, date, SUM(unit_price * quantity) AS daily_revenue FROM sales WHERE EXTRACT(YEAR FROM date) = 2021 GROUP BY 1,2 ) SELECT branch, MAX(daily_revenue) max_daily_revenue FROM daily_revenue GROUP BY 1 ORDER BY 2 DESC En esta consulta, un CTE llamado daily_revenue tiene las columnas sucursal, fecha y daily_revenue para cada fecha de 2021. Luego, en la consulta externa, obtenemos la mayor cantidad de ingresos para cada sucursal en 2021. El informe se ordena por max_daily_revenue en orden descendente. A continuación se muestran los resultados de esta consulta. branchmax_daily_revenue London-1575 London-2240 Paris-1135 Uso de CTEs en Consultas SQL avanzado Puede definir dos o más CTEs y utilizarlos en la consulta principal. En el siguiente ejemplo, le mostramos cómo dividir y organizar una consulta larga utilizando CTEs SQL. Al nombrar las diferentes partes de la consulta, las CTEs hacen que la consulta sea fácil de leer. Supongamos que queremos un informe con los ingresos mensuales totales de Londres en 2021, pero también queremos los ingresos de cada sucursal de Londres en el mismo informe. En este caso, creamos dos CTE y los unimos en la consulta principal. WITH london1_monthly_revenue AS ( SELECT EXTRACT(MONTH FROM date) as month, SUM(unit_price * quantity) AS revenue FROM sales WHERE EXTRACT(YEAR FROM date) = 2021 AND branch = 'London-1' GROUP BY 1 ), london2_monthly_revenue AS ( SELECT EXTRACT(MONTH FROM date) as month, SUM(unit_price * quantity) AS revenue FROM sales WHERE EXTRACT(YEAR FROM date) = 2021 AND branch = 'London-2' GROUP BY 1 ) SELECT l1.month, l1.revenue + l2.revenue AS london_revenue, l1.revenue AS london1_revenue, l2.revenue AS london2_revenue FROM london1_monthly_revenue l1, london2_monthly_revenue l2 WHERE l1.month = l2.month En la consulta anterior, definimos dos CTEs, london1_monthly_revenue y london2_monthly_revenuepara obtener los ingresos mensuales en 2021 de cada sucursal de Londres. Por último, unimos ambos CTEs utilizando la columna del mes y calculamos los ingresos totales de Londres sumando los ingresos de las dos sucursales. A continuación se muestra el resultado de la consulta: monthlondon_revenuelondon1_revenuelondon2_revenue 121055815240 En el siguiente ejemplo, obtenemos un informe para informar a cada sucursal de la fecha en la que se vendió el mayor ticket (es decir, el importe de la combinación artículo-cantidad) y el importe de este ticket. Para ello, necesitamos crear un CTE que clasifique los tickets (la columna position es la clasificación) para cada sucursal por el importe del ticket. WITH tickets AS ( SELECT distinct branch, date, unit_price * quantity AS ticket_amount, ROW_NUMBER() OVER ( PARTITION BY branch ORDER by unit_price * quantity DESC ) AS position FROM sales ORDER BY 3 DESC ) SELECT branch, date, ticket_amount FROM tickets WHERE position =1 En la consulta anterior, creamos un CTE con las columnas branch, date, ticket_amount, y position. Luego, en la consulta externa, filtramos sólo los registros con position = 1 para obtener lo que queremos, el ticket más grande por sucursal. El resultado de la consulta se muestra a continuación: branchdateticket_amount London-12021-11-2450 London-22021-11-1270 Paris-12021-12-780 CTEs anidados en consultas SQL El siguiente ejemplo muestra una CTE anidada. La idea es generar un informe con todos los artículos de precio superior a 90 dólares y la cantidad de estos artículos vendidos por la sucursal Londres-2. WITH over_90_items AS ( SELECT DISTINCT item, unit_price FROM sales WHERE unit_price >=90 ), london2_over_90 AS ( SELECT o90.item, o90.unit_price, coalesce(SUM(s.quantity), 0) as total_sold FROM over_90_items o90 LEFT JOIN sales s ON o90.item = s.item AND s.branch = 'London-2' GROUP BY o90.item, o90.unit_price ) SELECT item, unit_price, total_sold FROM london2_over_90; El primer CTE es over_90_itemsque selecciona todos los artículos cuyo precio es igual o superior a 90 $. El segundo CTE es london2_over_90que selecciona la cantidad vendida por Londres-2 de cada artículo incluido en over_90_items. Esta consulta tiene un CTE anidado: observe que FROM en el segundo CTE hace referencia al primero. Utilizamos LEFT JOIN sales porque es posible que Londres-2 no haya vendido todos los artículos de over_90_items. El resultado de la consulta es : itemunit_pricetotal_sold Cell Phone X11000 Cell Phone X21200 Cell Phone B2907 Antes de pasar a la siguiente sección, tengo algunos artículos que sugerir sobre expresiones comunes de tabla. Tanto "SQL CTEs Explained with Examples" como "Where Can I Find Good SQL CTE Exercises?" tienen muchos ejemplos y ejercicios. Consultas recursivas y expresiones de tabla comunes y Expresiones Comunes de Tabla En las bases de datos relacionales, es común tener tablas que representan jerarquías de datos como empleado-gerente, parte-subparte o padre-hijo. Para recorrer estas jerarquías en cualquier dirección (de arriba a abajo o de abajo a arriba), las bases de datos utilizan una construcción llamada CTE recursiva. RECURSIVE es una palabra reservada para definir una CTE para recorrer una estructura de datos recursiva. La forma de la consulta recursiva es la siguiente: WITH RECURSIVE cte_name AS ( CTE_query_definition -- non recursive query term UNION ALL CTE_query_definition -- recursive query term ) SELECT * FROM cte_name; Las consultas recursivas están fuera del alcance de este artículo introductorio, pero tengo otros tres para sugerir a aquellos que quieran más sobre el tema: "Cómo organizar consultas SQL con CTEs", "Hazlo en SQL: Recursive SQL Tree Traversal" y "Get to Know the Power of SQL Consultas recursivas y expresiones de tabla comunes". En ellos se explican en detalle las consultas recursivas con multitud de ejemplos. Las CTE de SQL son un potente recurso Las expresiones comunes de tabla son un poderoso recurso del lenguaje SQL. Nos permiten crear consultas más legibles y gestionar las diferencias de formato entre los datos de la tabla y los datos del informe. En este artículo, hemos cubierto qué es una CTE y cómo utilizarlas en diferentes tipos de consultas. También hemos mencionado que las CTE pueden utilizarse en consultas recursivas. Recomiendo el curso Consultas recursivas y expresiones de tabla comunes en LearnSQL.esdonde aprenderás de forma interactiva a trabajar con expresiones comunes de tabla en SQL. También aprenderás a procesar estructuras de datos recursivas como grafos y árboles en SQL utilizando CTEs recursivas. Además, echa un vistazo a la pista SQL avanzadoen el que irás más allá de los conceptos básicos para convertirte en un maestro de SQL. Si necesitas prepararte para una entrevista SQL, hay un interesante artículo "Top 5 SQL CTE Interview Questions" que trata las expresiones de tabla más comunes desde otra perspectiva. Si has aprendido a utilizar CTEs, entonces estás un paso más adelante en el camino hacia un desarrollador SQL. ¡Sigue creciendo! Tags: SQL aprender SQL CTE