SET dialect = 'clickhouse' permite volver atrás. SET es la única instrucción SQL reconocida mientras
el dialecto KQL está activo, por lo que siempre se puede salir de él desde una sesión.
Compatibilidad
Se trata deliberadamente de un subconjunto reducido. Una construcción de KQL se traduce con la semántica documentada por Kusto o se rechaza explícitamente con un error de análisis; no se hacen aproximaciones silenciosas. Si una consulta se analiza correctamente, su resultado debe coincidir con el de Kusto. Fuentes: un nombre de tabla,print, datatable, range, una canalización entre paréntesis y union.
Un range puede ir de un número en incrementos de un número, de un datetime en incrementos de un timespan o de un timespan en incrementos de
un timespan.
Operadores: where / filter, extend, project, project-away, project-keep,
project-rename, summarize, sort by / order by, take / limit, top, distinct,
count, mv-expand, join, union, as, render.
Operadores escalares: ==, !=, <, <=, >, >=, =~, !~, in, in~, between,
contains, startswith, endswith, has, hasprefix, hassuffix, sus variantes _cs
(sensibles a mayúsculas y minúsculas) y ! (negadas), has_any, has_all y matches regex.
in y !in también aceptan una expresión tabular cuya primera columna proporciona los valores
(x in (T | project key)); in~ solo acepta una lista. Un nombre aislado dentro de in (...) que no esté vinculado mediante
let se interpreta como una columna, ya que el analizador no dispone de un esquema para distinguir una columna de una tabla;
vincule la tabla con let, califíquela (db.table) o añada una canalización para obtener la forma tabular.
Sentencias: let, que vincula un escalar, una expresión tabular completa o una función:
T: (*) o T: (col: type, ...), que deben aparecer primero. Un parámetro tabular que
nombra sus columnas expone al cuerpo solo esas columnas del argumento, por lo que se rechaza un cuerpo que lee una
columna no declarada, incluso si el argumento concreto la contiene; T: (*)
transmite el argumento tal como está. Los tipos declarados se validan en el límite de la llamada:
se rechaza un argumento —o una columna declarada de un argumento tabular— cuyo tipo no pertenezca al
tipo KQL declarado, se aplica una conversión sin pérdida como de long a real, y
un valor que no se ajusta al tipo declarado —por ejemplo, un desbordamiento de int— genera un error en lugar
de truncarse silenciosamente. Los argumentos pueden pasarse por
nombre en cualquier orden (f(c = 7, a = 12)). Un cuerpo consta de cualquier número de sentencias let seguidas de
una expresión, y puede acceder a las vinculaciones que lo engloban. Una función cuyo cuerpo es una
canalización es una tabla en lugar de un valor, por lo que se rechaza donde se espera una expresión:
en extend, where o print. Una función sin parámetros puede
llamarse con o sin paréntesis. Se acepta view () y, dado que aquí no se resuelven
comodines de union *, significa lo mismo que (). La recursión se rechaza, como en Kusto.
Un let crea una vinculación solo para la sentencia que le sigue, porque una sentencia KQL equivale a una
consulta de ClickHouse; esto también evita que una vinculación se filtre a una consulta concurrente. Un
nombre que necesiten dos sentencias debe vincularse dos veces.
Literales: cadenas —incluidas las literales textuales @'...'—, números, datetime(...), guid(...),
intervalos de tiempo como 1d / 2.5h / 500ms y arrays dynamic([...]).
Se traducen alrededor de 130 funciones escalares y de agregación. Como en Kusto, las funciones de agregación
solo pueden llamarse en la lista de agregación de summarize; print count() se
rechaza en lugar de pasarse a la función de agregación de ClickHouse del mismo nombre.
También se puede acceder a las funciones de ClickHouse. Un nombre que el registro de KQL no reconoce se
pasa a ClickHouse con la grafía utilizada, por lo que una consulta puede usar cualquier función que el servidor
ofrezca:
range es el caso más claro: range(1, 3, 1) es [1, 2, 3] en Kusto y [1, 2] en
ClickHouse, por lo que usarlo en KQL produce un error en lugar de un resultado incorrecto.
Cobertura con respecto a la referencia de Kusto
Comparada con los propios índices de Microsoft (operadores tabulares, funciones escalares, funciones de agregación):
Los operadores compatibles son los que se enseñan en el tutorial de Microsoft Learn common operators,
además de
datatable, range, print, union y join; suficientes para el tipo de consultas que
se desarrollan en ese tutorial y en la KQL Quick Reference.
Lo que no se admite
Se rechazan con un error de análisis, en lugar de traducirse de forma incorrecta:- Operadores:
search,parse,mv-apply,lookup,evaluate,invoke,facet,top-nested,make-series,sample,serialize,partition,rangecomo operador. - Funciones: la familia
series_*,bag_*/pack_*,parse_url,parse_csv,parse_json,todynamic,toscalar,format_timespan,format_datetime,extract_all,range, la familiapercentiles*y las funciones de ventanarow_*. (format_datetimeyextract_allse rechazan en lugar de aproximarse: los especificadores de formatoyyyy-MM-ddde Kusto no son los de ClickHouse, yextract_allde Kusto devuelve un array por cada grupo de captura.) - Nombres de Kusto que entran en conflicto con una función de ClickHouse de significado distinto:
range(mostrado arriba),repeat,replace,translateymaterialize. Dejarlos pasar calcularía silenciosamente algo diferente —repeat(1, 3)de Kusto es el array[1, 1, 1], mientras querepeatde ClickHouse repite una cadena —, por lo que todos se rechazan por nombre. - Las funciones geoespaciales que aceptan o devuelven GeoJSON — todas las
geo_*_to_central_pointy todo lo que opera con polígonos y líneas. Las funciones de puntos, geohash y H3 que funcionan con longitud/latitud sin formato sí se admiten.geo_point_to_s2cellno se admite: ClickHouse no tiene formato de token S2. - Objetos
dynamic(dynamic({"a": 1})), acceso a miembros (x.y) y búsqueda por clave (x['k']). Solo los arraysdynamicse asignan aArrayde ClickHouse.dynamiccomo tipo declarado — en un esquema dedatatable, untypeof(...)o un parámetro de función — también se rechaza: la anotación no incluye ningún tipo de elemento, por lo que no hay nada a lo que asignarlo de forma fiel. - Referencias entre clústeres y entre bases de datos, como
cluster(...)ydatabase(...). - Sugerencias de consulta y de
join(hint.strategy,hint.shufflekey, …). - Opciones de operador:
mv-expand ... to typeof(T)/limit N/bagexpansion, sugerencias desummarize,union kind=/withsource=/isfuzzy=,join hint.*. - Patrones de columnas con comodines en
project-awayyproject-keep(project-away Tmp*): expandir uno requiere el esquema, que no es visible durante el análisis sintáctico. Enumere las columnas explícitamente. - Todo el mecanismo de complementos de
evaluate, y con élbag_unpack,pivot,narrow,python,Ry el resto. - Sentencias de aplicación:
alias database,declare pattern,declare query_parameters,restrict access to. - Literales de cadena ofuscados (
h"...") y literales multilínea (triple acento grave).
Comportamientos que conviene conocer
- Los intervalos de tiempo son valores
Interval.1dse convierte entoIntervalNanosecond(86400000000000). Configureinterval_output_format = 'kusto'para mostrarlos al estilo de Kusto (1.00:00:00) en lugar de como un número. - La división sigue el comportamiento de Kusto:
7 / 2es3, porque ambos operandos son enteros, y un intervalo de tiempo dividido por otro es su razón en valores reales (15ms / 10mses1.5). Esto se implementa mediantekqlDivide, que decide según los tipos de los argumentos. - Restar dos valores de fecha y hora devuelve un número de segundos, mientras que Kusto devuelve un intervalo de tiempo. Sumar o restar un intervalo de tiempo funciona como se espera.
sortusa el orden descendente de forma predeterminada, a diferencia de SQL, y coloca los valores nulos en el extremo inferior.project-renamemueve la columna renombrada al final de la fila. Kusto conserva su posición original; reproducir este comportamiento requeriría conocer el esquema durante el análisis.unionrequiere que los operandos tengan esquemas compatibles. Kusto se amplía a la unión de todas las columnas y rellena con valores nulos;UNION ALLde ClickHouse no lo hace.- Los operadores de cadenas son funciones de coincidencia, no patrones
LIKE.contains '50%'busca un signo de porcentaje literal. geo_*acepta la longitud antes que la latitud, como Kusto.geo_distance_2pointsusagreatCircleDistancede ClickHouse, una aproximación rápida que difiere de Kusto en la cuarta cifra significativa —unos 600 m en 1500 km—, yuse_spheroid = trueseleccionageoDistance, la fórmula elipsoidal, como en Kusto. La coincidencia exacta no es el objetivo: estas funciones suelen usarse para filtrar, no para generar informes. Tenga en cuenta que una coordenada fuera de [-180, 180] o [-90, 90] produce un número sin sentido en lugar del valor nulo que devuelve Kusto: ninguna de las funciones de ClickHouse comprueba el rango de sus argumentos, y hacerlo costaría ocho comparaciones por fila.dayofweek()devuelve un intervalo de tiempo, no un número: un lunes es1.00:00:00.tohex()representa un valor negativo con un ancho de 64 bits. Kusto lo representa con el ancho del propio tipo del argumento, que no es visible durante el análisis.- Los valores de fecha y hora son valores
DateTime64reales, por lo que se muestran al estilo de ClickHouse (2017-01-01 00:00:00) en lugar de al de Kusto (2017-01-01T00:00:00.0000000). La implementación anterior producía una cadena formateada, que se parecía a Kusto, pero no se comparaba ni ordenaba como un valor de fecha y hora. - Las agregaciones paramétricas de ClickHouse (
quantileExact(0.5)(x)) no tienen sintaxis en KQL. Utilice una alternativa con nombre, comomedianExact(x).