Common Table Expression (CTE): la sentencia WITH en PostgreSQL.

Hace tiempo escribí una entrada sobre el uso de CTE en SQL-Server de Microsoft y no hace mucho en dicha entrada me preguntaron si podría usarse también una CTE en PostgreSQL. La respuesta es que sí, existe este recurso también en ese sistema gestor de bases de datos.

Sintaxis básica de una CTE

Recuerda, una CTE es un artefacto que nos permite mantener en memoria el resultado de una consulta para poder utilizarlo como si se tratase de una tabla o vista más.

En PostgreSQL usaría la misma sintaxis que en SQL-Server: tras la instrucción WITH definimos el nombre de la CTE y podemos opcionalmente agregar también los nombres que queramos dar a las columnas de la tabla que devolverá como resultado (si no lo hacemos entonces se usarán por defecto los nombres de las columnas que traigamos en la consulta). Dentro del cuerpo de la instrucción WITH definimos la consulta que queramos usar en la CTE. Finalmente ya podremos usar nuestra CTE dentro de una consulta. En fin, que lo básico sería tal que así:

WITH cte_name (column_list) AS (
    Select * from TablaQueNecesitemos
)

El mismo ejemplo que usé en la entrada sobre SQL-Server nos vale para aquí, una CTE sobre dos tablas (vendedores y ventas) para ver el total de ventas de cada uno ese año:

WITH Ventas_CTE (IdVendedor, NombreVendedor, TotalVendido)  
AS  
(  
    SELECT 
      v.Id as IdVendedor, 
      v.Nombre as NombreVendedor, 
      SUM(vt.Importe) AS TotalVentas 
    FROM Vendedores v inner join ventas vt on v.Id = vt.IdVendedor
    WHERE YEAR(vt.Fecha)=2018
)  

Después podríamos usar esa CTE como una tabla más en cualquier consulta de SELECT, INSERT,UPDATE o DELETE. Recordad que como en SQL-Server no podremos usar cláusulas coo ORDER BY o FOR BROWSE, algo que tampoco tendría mucho sentido por otra parte.

¿Por qué usar una CTE?

La misma pregunta que nos hacíamos en el primer artículo. Hay motivos varios para usar una CTE con PostrgreSQL:

  • Hacer más legible y más entendible una consulta compleja, permitiéndonos prescindir de variables de tabla y subconsultas, consiguiendo un código más ordenado y limpio sin penalizar el rendimiento.
  • La posibilidad de crear consultas recursivas (un tema del que prometí escribir hace dos años y se me pasó)
  • La posibilidad de usar funciones de agregado o funciones ventana y poder operar con ellas después.