SELECT puede ir seguida de una cadena de operadores de canalización. Cada operador comienza con el token |>, toma como entrada el resultado de la consulta que lo precede y le aplica una transformación adicional. Dentro de cada operador se utiliza la sintaxis habitual de ClickHouse.
Los operadores de canalización son una extensión de la sintaxis: cada operador encapsula la consulta que lo precede en una subconsulta, por lo que el AST resultante es el mismo que el de la consulta equivalente escrita con subconsultas anidadas, y la consulta anterior equivale a:
Consultas con FROM
FROM, y la cláusula SELECT es opcional en estas consultas. Si se omite, la consulta funciona como si se hubiera escrito SELECT *:
AS, como en la cláusula FROM de una consulta SELECT ordinaria: FROM orders o WHERE o.amount > 100. La única excepción es un alias escrito como la palabra sin adornos select: después de las tablas, inicia la cláusula SELECT explícita en lugar de tratarse como un alias. Una tabla llamada select no se ve afectada y conserva su propio alias: FROM select s WHERE s.id = 1.
La cláusula SELECT no puede omitirse cuando el desplazamiento de muestreo de la última tabla también podría interpretarse como un OFFSET de nivel de consulta, ya que en FROM t SAMPLE 1/10 OFFSET 5 el OFFSET pertenece a SAMPLE, mientras que en FROM t SAMPLE 1/10 SELECT * OFFSET 5 es un OFFSET de nivel de consulta; el SELECT explícito es necesario para distinguir ambos casos. Cuando la consulta continúa con una cláusula a la que no puede preceder un OFFSET de nivel de consulta, no hay ambigüedad y la cláusula SELECT es opcional, como de costumbre: FROM t SAMPLE 1/10 OFFSET 5 WHERE x > 0, FROM t SAMPLE 1/10 OFFSET 5 JOIN dim USING (id).
Operadores
WHERE
|> WHERE condition filtra las filas de entrada. Cuando se aplica después de una agregación, funciona como HAVING:
SELECT
|> SELECT [DISTINCT] expr1 [AS alias1], ... deja únicamente las expresiones indicadas como columnas de salida:
SELECT de una consulta ordinaria; en este caso, puede ir seguida del final de la consulta o del siguiente operador |>: FROM orders |> SELECT customer, amount, |> LIMIT 1. Lo mismo se aplica a los operadores EXTEND y AGGREGATE.
EXTEND
|> EXTEND expr1 [AS alias1], ... agrega las expresiones indicadas a las columnas de entrada; equivale a SELECT *, expr1 AS alias1, ...:
SET
|> SET column1 = expr1, ... sustituye los valores de las columnas indicadas; equivale a SELECT * REPLACE (expr1 AS column1, ...):
DROP
|> DROP column1, ... elimina las columnas indicadas; equivale a SELECT * EXCEPT (column1, ...):
AS
|> AS alias asigna un alias a la entrada del operador siguiente para poder referenciarla en dicho operador, lo que resulta especialmente útil en los joins:
AGGREGATE
|> AGGREGATE agg1 [AS alias1], ... [GROUP BY expr1 [AS alias1], ...] realiza una agregación de las filas de entrada. Las columnas de salida son las columnas de agrupación, seguidas de las columnas agregadas. Sin GROUP BY, toda la entrada se agrega en una única fila:
DISTINCT
|> DISTINCT elimina las filas duplicadas; es equivalente a SELECT DISTINCT *.
ORDER BY
|> ORDER BY expr1 [ASC/DESC], ... ordena las filas de entrada. Se admite toda la sintaxis de la cláusula ORDER BY, incluidos ORDER BY ALL, WITH FILL e INTERPOLATE:
LIMIT y OFFSET
|> LIMIT length [OFFSET offset] y |> OFFSET offset limitan el número de filas:
JOIN y ARRAY JOIN
|> [GLOBAL] [ANY/ALL/ASOF/SEMI/ANTI] [INNER/LEFT/RIGHT/FULL/CROSS] JOIN table [ON expr | USING (columns)] combina la entrada con otra tabla, subconsulta o función de tabla. Se admiten todos los tipos de JOIN y ARRAY JOIN, y un mismo operador puede contener varios joins, como una cláusula FROM:
ON). Los operadores posteriores ven las columnas combinadas del resultado del JOIN, como después de un SELECT *.
También se admite la sintaxis de CROSS JOIN con coma, con la entrada del operador como lado izquierdo: FROM customers |> AS c |> , orders. Al igual que con los demás JOIN, la entrada necesita un alias cuando la configuración joined_subquery_requires_alias está habilitada (lo está de forma predeterminada).
Al igual que en la cláusula FROM de una consulta ordinaria, no se admite un JOIN con coma (CROSS JOIN) inmediatamente después de un ARRAY JOIN: una coma después de ARRAY JOIN siempre forma parte de su lista de expresiones.
UNION, INTERSECT y EXCEPT
|> UNION [ALL/DISTINCT] (query1) [, (query2), ...], |> INTERSECT [ALL/DISTINCT] ... y |> EXCEPT [ALL/DISTINCT] ... combinan la entrada con los resultados de otras consultas:
Notas
- La cláusula
WITHde la consulta permanece visible en todos los operadores de canalización posteriores, tanto para alias escalares como para CTE:WITH 10 AS threshold FROM t |> WHERE x < threshold. - En
INSERT ... SELECT, una cláusulaWITHescrita antes deINSERTse adjunta alSELECTgenerado más externo y llega a las etapas internas de la canalización durante la interpretación mediante el ajusteenable_global_with_statement(habilitado de forma predeterminada), del mismo modo que llega a una subconsulta anidada escrita manualmente. Si ese ajuste está deshabilitado, los alias y CTE de unWITHcon ámbito deINSERTno son visibles dentro de las etapas de canalización, al igual que no lo son dentro de una subconsulta escrita manualmente. - Como cualquier consulta
SELECT, la consulta generada por un operador de canalización puede terminar con una cláusulaSETTINGS, que se adjunta a dicha consulta generada:FROM t |> LIMIT 1 SETTINGS max_threads = 1equivale aSELECT * FROM (SELECT * FROM t) LIMIT 1 SETTINGS max_threads = 1. Esto también funciona cuando no hay una pasada independiente para los ajustes de consulta, como en una subconsulta, enCREATE VIEWo en la función de tablaview. Una cláusulaSETTINGSen medio de una cadena permanece en su etapa, que se convierte en una subconsulta para el siguiente operador. Después de una operación de conjuntos con un operando entre paréntesis, no se acepta unSETTINGSal final; la consulta equivalente con subconsultas tampoco puede tener una cláusulaSETTINGSen esa posición. - Una cláusula
SETTINGSde la consulta anterior al primer operador de canalización permanece en esa consulta, que se convierte en una subconsulta del envoltorio generado. Los ajustes ordinarios siguen funcionando, porque los ajustes de una subconsulta se aplican al interpretarla. La única excepción es el par de ajustes que selecciona el analizador de consultas,enable_analyzery su aliasallow_experimental_analyzer: no se permite modificarlos en una subconsulta, por lo queSELECT number FROM numbers(1) SETTINGS enable_analyzer = 0 |> LIMIT 1generaINCORRECT_QUERY, al igual que la instrucción equivalente escrita manualmenteSELECT * FROM (SELECT number FROM numbers(1) SETTINGS enable_analyzer = 0) LIMIT 1. Escriba estos dos ajustes después del último operador de canalización o páselos fuera de la consulta. - Los operadores de canalización se aplican a toda la consulta que los precede, incluidas las operaciones de conjuntos: en
SELECT 1 UNION ALL SELECT 2 |> AGGREGATE count(), la agregación se aplica al resultado deUNION ALL. Para continuar una consulta conUNIONdespués de un operador de canalización, use el operador|> UNIONo paréntesis. - Los operadores de canalización se pueden usar en cualquier lugar donde se espere una consulta
SELECT: en subconsultas, enINSERT ... SELECT(incluida la formaINSERT INTO t FROM src |> ...), enCREATE VIEW, en la función de tablaview, etc. - No se proporciona un operador independiente para cambiar el nombre de columnas directamente; use
|> SELECT * EXCEPT (old_name), old_name AS new_nameo los operadoresSETyDROP.