Expresiones de tabla comunes
Las expresiones de tabla comunes representan subconsultas con nombre. Se puede hacer referencia a ellas por su nombre en cualquier parte de una consultaSELECT donde se permita una expresión de tabla.
Se puede hacer referencia a las subconsultas con nombre dentro del ámbito de la consulta actual o de los ámbitos de las subconsultas hijas.
Cada referencia a una expresión de tabla común en consultas SELECT siempre se sustituye por la subconsulta de su definición si la CTE no está definida explícitamente como materializada (consulte Expresiones de tabla comunes materializadas).
La recursión se evita ocultando la CTE actual del proceso de resolución de identificadores.
Tenga en cuenta que las CTE no garantizan los mismos resultados en todos los lugares donde se usan, porque la consulta se vuelve a ejecutar en cada caso.
Sintaxis
Ejemplo
Un ejemplo de cuándo se vuelve a ejecutar una subconsulta:1000000
Sin embargo, como hacemos referencia a cte_numbers dos veces, se generan números aleatorios cada vez y, por lo tanto, vemos resultados aleatorios distintos, 280501, 392454, 261636, 196227, y así sucesivamente…
Expresiones de tabla comunes materializadas
De forma predeterminada, ClickHouse inserta en línea la subconsulta de una CTE en cada punto en el que se hace referencia a ella, volviéndola a ejecutar cada vez. Agregar la palabra claveMATERIALIZED indica a ClickHouse que ejecute la subconsulta de la CTE exactamente una vez, almacene los resultados en una tabla temporal y resuelva todas las referencias a partir de esa tabla.
Esto resulta especialmente útil cuando se hace referencia a la misma CTE varias veces en una consulta (p. ej., en autouniones o en varias subconsultas IN), porque el cálculo subyacente solo se realiza una vez.
Las CTE materializadas son una característica experimental.
Requieren que la configuración
enable_materialized_cte esté habilitada.
Si la configuración está deshabilitada, se ignora la palabra clave MATERIALIZED: la CTE se inserta en línea en cada referencia como una CTE normal y se registra una advertencia.Sintaxis
Cuándo usar
Los CTE materializados son más útiles cuando:- Se hace referencia al mismo CTE más de una vez en una consulta.
Sin
MATERIALIZED, cada referencia vuelve a ejecutar la subconsulta de forma independiente. - El CTE contiene funciones no deterministas como
generateRandom. La materialización garantiza que todas las referencias vean los mismos datos. - El CTE implica cálculos costosos (agregaciones, joins, escaneos grandes) que no deberían repetirse.
Ejemplos
Ejemplo 1: Autounión en una CTE materializada SinMATERIALIZED, ambos lados de la unión ejecutarían la subconsulta de forma independiente.
Con MATERIALIZED, la tabla se escanea una sola vez y ambos lados de la unión leen de la misma tabla temporal.
generateRandom producen resultados distintos en cada referencia.
Materializar la CTE garantiza la consistencia:
1000000.
Ejemplo 3: Encadenamiento de CTE materializadas
Las CTE materializadas pueden hacer referencia a otras CTE materializadas.
ClickHouse resuelve las dependencias y las materializa en el orden adecuado:
Restricciones
- Se requiere una configuración experimental: La configuración
enable_materialized_ctedebe estar habilitada. Si está deshabilitada, se ignora la palabra claveMATERIALIZED: el CTE se inserta en línea en cada referencia como un CTE normal y se registra una advertencia. - No compatible con
RECURSIVE: No se permite combinar las palabras claveMATERIALIZEDyRECURSIVE, y ello da lugar a una excepciónUNSUPPORTED_METHOD. - Los CTE correlacionados no están permitidos: Un CTE materializado no puede hacer referencia a columnas de ámbitos externos de la consulta.
Expresiones escalares comunes
ClickHouse le permite declarar alias para expresiones escalares arbitrarias en la cláusulaWITH.
Las expresiones escalares comunes pueden usarse en cualquier parte de la consulta.
Si una expresión escalar común hace referencia a algo distinto de un literal constante, puede dar lugar a la presencia de variables libres.
ClickHouse resuelve cualquier identificador en el ámbito más cercano posible, lo que significa que las variables libres pueden hacer referencia a entidades inesperadas en caso de conflictos de nombres o dar lugar a una subconsulta correlacionada.
Se recomienda definir CSE como una función lambda, vinculando todos los identificadores usados para lograr un comportamiento más predecible en la resolución de los identificadores de la expresión.
Sintaxis
Ejemplos
Ejemplo 1: Uso de una expresión constante a modo de “variable”extension no está vinculado en el cuerpo de la función lambda gen_name.
Aunque extension se define como '.txt' como una expresión escalar común en el ámbito de la definición y el uso de generated_names, se resuelve como una columna de la tabla extension_list, porque está disponible en la subconsulta generated_names.
sum(bytes)
Consultas recursivas
El modificador opcionalRECURSIVE permite que una consulta WITH haga referencia a sus propios resultados. Ejemplo:
Ejemplo: Sumar los enteros del 1 al 100
Los CTE recursivos dependen del analizador de consultas, introducido en la versión
24.3, que es el predeterminado desde esa versión y obligatorio desde la 26.9. En versiones anteriores en las que el analizador siga deshabilitado en la instancia, el rol o el perfil, un CTE recursivo genera una excepción (UNKNOWN_TABLE) o (UNSUPPORTED_METHOD); habilita allí la configuración enable_analyzer o actualiza la versión.WITH recursiva consta siempre de un término no recursivo, luego UNION ALL y, después, un término recursivo, donde solo el término recursivo puede contener una referencia a la propia salida de la consulta. Una consulta CTE recursiva se ejecuta de la siguiente manera:
- Evaluar el término no recursivo. Colocar el resultado de la consulta del término no recursivo en una tabla de trabajo temporal.
- Mientras la tabla de trabajo no esté vacía, repetir estos pasos:
- Evaluar el término recursivo, sustituyendo la autorreferencia recursiva por el contenido actual de la tabla de trabajo. Colocar el resultado de la consulta del término recursivo en una tabla intermedia temporal.
- Reemplazar el contenido de la tabla de trabajo por el de la tabla intermedia y, a continuación, vaciar la tabla intermedia.
Orden de búsqueda
Para crear un orden de recorrido en profundidad, calculamos, para cada fila de resultado, un Array de filas que ya hemos visitado: Ejemplo: Recorrido de árbol en profundidadDetección de ciclos
Primero, vamos a crear la tabla del grafo:Maximum recursive CTE evaluation depth:
Consultas infinitas
También es posible usar consultas CTE recursivas infinitas si la consulta externa usaLIMIT:
Ejemplo: Consulta CTE recursiva infinita
Coma final
Se permite una coma después del último elemento de la cláusulaWITH: