diff --git a/docs/es/sql-reference/statements/select.md b/docs/es/sql-reference/statements/select.md index 5cbf2d454e3..fac4d8b80e0 100644 --- a/docs/es/sql-reference/statements/select.md +++ b/docs/es/sql-reference/statements/select.md @@ -1,11 +1,11 @@ --- machine_translated: true -machine_translated_rev: 3e185d24c9fe772c7cf03d5475247fb829a21dfa +machine_translated_rev: 0f7ef7704d018700049223525bad4a63911b6e70 toc_priority: 33 toc_title: SELECT --- -# SELECCIONAR Consultas Sintaxis {#select-queries-syntax} +# SELECCIONAR consultas Sintaxis {#select-queries-syntax} `SELECT` realiza la recuperación de datos. @@ -250,7 +250,7 @@ Aquí, se toma una muestra del 10% de la segunda mitad de los datos. ### ARRAY JOIN Cláusula {#select-array-join-clause} -Permite ejecutar `JOIN` con una matriz o estructura de datos anidada. La intención es similar a la [arrayJoin](../../sql-reference/functions/array-join.md#functions_arrayjoin) función, pero su funcionalidad es más amplia. +Permite ejecutar `JOIN` con una matriz o estructura de datos anidada. La intención es similar a la [arrayJoin](../functions/array-join.md#functions_arrayjoin) función, pero su funcionalidad es más amplia. ``` sql SELECT @@ -327,7 +327,7 @@ LEFT ARRAY JOIN arr; └─────────────┴─────┘ ``` -#### Uso De Alias {#using-aliases} +#### Uso de alias {#using-aliases} Se puede especificar un alias para una matriz en el `ARRAY JOIN` clausula. En este caso, este alias puede acceder a un elemento de matriz, pero el nombre original tiene acceso a la matriz en sí. Ejemplo: @@ -405,7 +405,7 @@ ARRAY JOIN arr AS a, arrayEnumerate(arr) AS num; └───────┴─────────┴───┴─────┴─────────────────────┘ ``` -#### ARRAY JOIN Con Estructura De Datos Anidada {#array-join-with-nested-data-structure} +#### ARRAY JOIN con estructura de datos anidada {#array-join-with-nested-data-structure} `ARRAY`JOIN\`\` también funciona con [estructuras de datos anidados](../../sql-reference/data-types/nested-data-structures/nested.md). Ejemplo: @@ -534,7 +534,7 @@ FROM Los nombres de tabla se pueden especificar en lugar de `` y ``. Esto es equivalente a la `SELECT * FROM table` subconsulta, excepto en un caso especial cuando la tabla tiene [Unir](../../engines/table-engines/special/join.md) engine – an array prepared for joining. -#### Tipos Compatibles De `JOIN` {#select-join-types} +#### Tipos admitidos de `JOIN` {#select-join-types} - `INNER JOIN` (o `JOIN`) - `LEFT JOIN` (o `LEFT OUTER JOIN`) @@ -604,7 +604,776 @@ USING (equi_column1, ... equi_columnN, asof_column) Por ejemplo, considere las siguientes tablas: -\`\`\` texto -table\_1 table\_2 + table_1 table_2 + event | ev_time | user_id event | ev_time | user_id + ----------|---------|---------- ----------|---------|---------- + ... ... + event_1_1 | 12:00 | 42 event_2_1 | 11:59 | 42 + ... event_2_2 | 12:30 | 42 + event_1_2 | 13:00 | 42 event_2_3 | 13:00 | 42 + ... ... -evento \| ev\_time \| user\_id evento \| ev\_time \| user\_id +`ASOF JOIN` puede tomar la marca de tiempo de un evento de usuario de `table_1` y encontrar un evento en `table_2` donde la marca de tiempo es la más cercana a la marca de tiempo del evento `table_1` correspondiente a la condición de coincidencia más cercana. Los valores de marca de tiempo iguales son los más cercanos si están disponibles. Aquí, el `user_id` se puede utilizar para unirse a la igualdad y el `ev_time` columna se puede utilizar para unirse en el partido más cercano. En nuestro ejemplo, `event_1_1` se puede unir con `event_2_1` y `event_1_2` se puede unir con `event_2_3`, pero `event_2_2` no se puede unir. + +!!! note "Nota" + `ASOF` unirse es **ni** apoyado en el [Unir](../../engines/table-engines/special/join.md) motor de mesa. + +Para establecer el valor de rigor predeterminado, utilice el parámetro de configuración de sesión [Por favor, introduzca su dirección de correo electrónico](../../operations/settings/settings.md#settings-join_default_strictness). + +#### GLOBAL JOIN {#global-join} + +Cuando se utiliza una normal `JOIN`, la consulta se envía a servidores remotos. Las subconsultas se ejecutan en cada una de ellas para crear la tabla correcta, y la unión se realiza con esta tabla. En otras palabras, la tabla correcta se forma en cada servidor por separado. + +Cuando se utiliza `GLOBAL ... JOIN`, primero el servidor requestor ejecuta una subconsulta para calcular la tabla correcta. Esta tabla temporal se pasa a cada servidor remoto y las consultas se ejecutan en ellos utilizando los datos temporales que se transmitieron. + +Tenga cuidado al usar `GLOBAL`. Para obtener más información, consulte la sección [Subconsultas distribuidas](#select-distributed-subqueries). + +#### Recomendaciones de uso {#usage-recommendations} + +Cuando se ejecuta un `JOIN`, no hay optimización del orden de ejecución en relación con otras etapas de la consulta. La combinación (una búsqueda en la tabla de la derecha) se ejecuta antes de filtrar `WHERE` y antes de la agregación. Para establecer explícitamente el orden de procesamiento, recomendamos ejecutar un `JOIN` subconsulta con una subconsulta. + +Ejemplo: + +``` sql +SELECT + CounterID, + hits, + visits +FROM +( + SELECT + CounterID, + count() AS hits + FROM test.hits + GROUP BY CounterID +) ANY LEFT JOIN +( + SELECT + CounterID, + sum(Sign) AS visits + FROM test.visits + GROUP BY CounterID +) USING CounterID +ORDER BY hits DESC +LIMIT 10 +``` + +``` text +┌─CounterID─┬───hits─┬─visits─┐ +│ 1143050 │ 523264 │ 13665 │ +│ 731962 │ 475698 │ 102716 │ +│ 722545 │ 337212 │ 108187 │ +│ 722889 │ 252197 │ 10547 │ +│ 2237260 │ 196036 │ 9522 │ +│ 23057320 │ 147211 │ 7689 │ +│ 722818 │ 90109 │ 17847 │ +│ 48221 │ 85379 │ 4652 │ +│ 19762435 │ 77807 │ 7026 │ +│ 722884 │ 77492 │ 11056 │ +└───────────┴────────┴────────┘ +``` + +Las subconsultas no permiten establecer nombres ni usarlos para hacer referencia a una columna de una subconsulta específica. +Las columnas especificadas en `USING` debe tener los mismos nombres en ambas subconsultas, y las otras columnas deben tener un nombre diferente. Puede usar alias para cambiar los nombres de las columnas en subconsultas (el ejemplo usa los alias `hits` y `visits`). + +El `USING` clause especifica una o más columnas a unir, lo que establece la igualdad de estas columnas. La lista de columnas se establece sin corchetes. No se admiten condiciones de unión más complejas. + +La tabla correcta (el resultado de la subconsulta) reside en la RAM. Si no hay suficiente memoria, no puede ejecutar una `JOIN`. + +Cada vez que se ejecuta una consulta `JOIN`, la subconsulta se ejecuta de nuevo porque el resultado no se almacena en caché. Para evitar esto, use el especial [Unir](../../engines/table-engines/special/join.md) motor de tabla, que es una matriz preparada para unirse que siempre está en RAM. + +En algunos casos, es más eficiente de usar `IN` en lugar de `JOIN`. +Entre los diversos tipos de `JOIN` el más eficiente es `ANY LEFT JOIN`, entonces `ANY INNER JOIN`. Los menos eficientes son `ALL LEFT JOIN` y `ALL INNER JOIN`. + +Si necesita un `JOIN` para unirse a tablas de dimensión (son tablas relativamente pequeñas que contienen propiedades de dimensión, como nombres para campañas publicitarias), un `JOIN` podría no ser muy conveniente debido al hecho de que se vuelve a acceder a la tabla correcta para cada consulta. Para tales casos, hay un “external dictionaries” característica que debe utilizar en lugar de `JOIN`. Para obtener más información, consulte la sección [Diccionarios externos](../dictionaries/external-dictionaries/external-dicts.md). + +**Limitaciones de memoria** + +ClickHouse utiliza el [hash unirse](https://en.wikipedia.org/wiki/Hash_join) algoritmo. ClickHouse toma el `` y crea una tabla hash para ello en RAM. Si necesita restringir el consumo de memoria de la operación de unión, use la siguiente configuración: + +- [Método de codificación de datos:](../../operations/settings/query-complexity.md#settings-max_rows_in_join) — Limits number of rows in the hash table. +- [Método de codificación de datos:](../../operations/settings/query-complexity.md#settings-max_bytes_in_join) — Limits size of the hash table. + +Cuando se alcanza cualquiera de estos límites, ClickHouse actúa como el [join\_overflow\_mode](../../operations/settings/query-complexity.md#settings-join_overflow_mode) configuración instruye. + +#### Procesamiento de celdas vacías o NULL {#processing-of-empty-or-null-cells} + +Al unir tablas, pueden aparecer las celdas vacías. Configuración [Sistema abierto.](../../operations/settings/settings.md#join_use_nulls) definir cómo ClickHouse llena estas celdas. + +Si el `JOIN` las llaves son [NULL](../data-types/nullable.md) campos, las filas donde al menos una de las claves tiene el valor [NULL](../syntax.md#null-literal) no se unen. + +#### Limitaciones de sintaxis {#syntax-limitations} + +Para múltiples `JOIN` cláusulas en una sola `SELECT` consulta: + +- Tomando todas las columnas a través de `*` está disponible solo si se unen tablas, no subconsultas. +- El `PREWHERE` cláusula no está disponible. + +Para `ON`, `WHERE`, y `GROUP BY` clausula: + +- Las expresiones arbitrarias no se pueden utilizar en `ON`, `WHERE`, y `GROUP BY` cláusulas, pero puede definir una expresión en un `SELECT` cláusula y luego usarla en estas cláusulas a través de un alias. + +### DONDE Cláusula {#select-where} + +Si hay una cláusula where, debe contener una expresión con el tipo UInt8. Esta suele ser una expresión con comparación y operadores lógicos. +Esta expresión se usará para filtrar datos antes de todas las demás transformaciones. + +Si los índices son compatibles con el motor de tablas de base de datos, la expresión se evalúa en función de la capacidad de usar índices. + +### PREWHERE Cláusula {#prewhere-clause} + +Esta cláusula tiene el mismo significado que la cláusula where. La diferencia radica en qué datos se leen de la tabla. +Al usar PREWHERE, primero solo se leen las columnas necesarias para ejecutar PREWHERE. Luego se leen las otras columnas que son necesarias para ejecutar la consulta, pero solo aquellos bloques donde la expresión PREWHERE es verdadera. + +Tiene sentido usar PREWHERE si hay condiciones de filtración utilizadas por una minoría de las columnas de la consulta, pero que proporcionan una filtración de datos fuerte. Esto reduce el volumen de datos a leer. + +Por ejemplo, es útil escribir PREWHERE para consultas que extraen un gran número de columnas, pero que solo tienen filtración para unas pocas columnas. + +PREWHERE solo es compatible con tablas de la `*MergeTree` familia. + +Una consulta puede especificar simultáneamente PREWHERE y WHERE. En este caso, PREWHERE precede WHERE. + +Si el ‘optimize\_move\_to\_prewhere’ La configuración se establece en 1 y PREWHERE se omite, el sistema utiliza la heurística para mover automáticamente partes de expresiones de WHERE a PREWHERE. + +### GRUPO POR Cláusula {#select-group-by-clause} + +Esta es una de las partes más importantes de un DBMS orientado a columnas. + +Si hay una cláusula GROUP BY, debe contener una lista de expresiones. Cada expresión se mencionará aquí como una “key”. +Todas las expresiones de las cláusulas SELECT, HAVING y ORDER BY deben calcularse a partir de claves o de funciones agregadas. En otras palabras, cada columna seleccionada de la tabla debe usarse en claves o dentro de funciones agregadas. + +Si una consulta solo contiene columnas de tabla dentro de funciones agregadas, se puede omitir la cláusula GROUP BY y se asume la agregación mediante un conjunto vacío de claves. + +Ejemplo: + +``` sql +SELECT + count(), + median(FetchTiming > 60 ? 60 : FetchTiming), + count() - sum(Refresh) +FROM hits +``` + +Sin embargo, a diferencia del SQL estándar, si la tabla no tiene ninguna fila (o no hay ninguna, o no hay ninguna después de usar WHERE para filtrar), se devuelve un resultado vacío, y no el resultado de una de las filas que contienen los valores iniciales de las funciones agregadas. + +A diferencia de MySQL (y conforme a SQL estándar), no puede obtener algún valor de alguna columna que no esté en una función clave o agregada (excepto expresiones constantes). Para evitar esto, puede usar el ‘any’ función de agregado (obtener el primer valor encontrado) o ‘min/max’. + +Ejemplo: + +``` sql +SELECT + domainWithoutWWW(URL) AS domain, + count(), + any(Title) AS title -- getting the first occurred page header for each domain. +FROM hits +GROUP BY domain +``` + +Para cada valor de clave diferente encontrado, GROUP BY calcula un conjunto de valores de función agregados. + +GROUP BY no se admite para columnas de matriz. + +No se puede especificar una constante como argumentos para funciones agregadas. Ejemplo: sum(1). En lugar de esto, puedes deshacerte de la constante. Ejemplo: `count()`. + +#### Procesamiento NULL {#null-processing} + +Para agrupar, ClickHouse interpreta [NULL](../syntax.md) como valor, y `NULL=NULL`. + +Aquí hay un ejemplo para mostrar lo que esto significa. + +Supongamos que tienes esta tabla: + +``` text +┌─x─┬────y─┐ +│ 1 │ 2 │ +│ 2 │ ᴺᵁᴸᴸ │ +│ 3 │ 2 │ +│ 3 │ 3 │ +│ 3 │ ᴺᵁᴸᴸ │ +└───┴──────┘ +``` + +Consulta `SELECT sum(x), y FROM t_null_big GROUP BY y` resultados en: + +``` text +┌─sum(x)─┬────y─┐ +│ 4 │ 2 │ +│ 3 │ 3 │ +│ 5 │ ᴺᵁᴸᴸ │ +└────────┴──────┘ +``` + +Se puede ver que `GROUP BY` para `y = NULL` resumir `x` como si `NULL` es este valor. + +Si pasa varias teclas a `GROUP BY` el resultado le dará todas las combinaciones de la selección, como si `NULL` fueron un valor específico. + +#### CON TOTALS Modificador {#with-totals-modifier} + +Si se especifica el modificador WITH TOTALS, se calculará otra fila. Esta fila tendrá columnas clave que contienen valores predeterminados (zeros o líneas vacías) y columnas de funciones agregadas con los valores calculados en todas las filas (el “total” valor). + +Esta fila adicional se genera en formatos JSON \*, TabSeparated \* y Pretty \*, por separado de las otras filas. En los otros formatos, esta fila no se genera. + +En los formatos JSON\*, esta fila se muestra como una ‘totals’ campo. En los formatos TabSeparated\*, la fila viene después del resultado principal, precedida por una fila vacía (después de los otros datos). En los formatos Pretty\*, la fila se muestra como una tabla separada después del resultado principal. + +`WITH TOTALS` se puede ejecutar de diferentes maneras cuando HAVING está presente. El comportamiento depende de la ‘totals\_mode’ configuración. +Predeterminada, `totals_mode = 'before_having'`. En este caso, ‘totals’ se calcula en todas las filas, incluidas las que no pasan por HAVING y ‘max\_rows\_to\_group\_by’. + +Las otras alternativas incluyen solo las filas que pasan por HAVING en ‘totals’, y comportarse de manera diferente con el ajuste `max_rows_to_group_by` y `group_by_overflow_mode = 'any'`. + +`after_having_exclusive` – Don't include rows that didn't pass through `max_rows_to_group_by`. En otras palabras, ‘totals’ tendrá menos o el mismo número de filas que si `max_rows_to_group_by` se omitieron. + +`after_having_inclusive` – Include all the rows that didn't pass through ‘max\_rows\_to\_group\_by’ en ‘totals’. En otras palabras, ‘totals’ tendrá más o el mismo número de filas como lo haría si `max_rows_to_group_by` se omitieron. + +`after_having_auto` – Count the number of rows that passed through HAVING. If it is more than a certain amount (by default, 50%), include all the rows that didn't pass through ‘max\_rows\_to\_group\_by’ en ‘totals’. De lo contrario, no los incluya. + +`totals_auto_threshold` – By default, 0.5. The coefficient for `after_having_auto`. + +Si `max_rows_to_group_by` y `group_by_overflow_mode = 'any'` no se utilizan, todas las variaciones de `after_having` son los mismos, y se puede utilizar cualquiera de ellos (por ejemplo, `after_having_auto`). + +Puede usar WITH TOTALS en subconsultas, incluidas las subconsultas en la cláusula JOIN (en este caso, se combinan los valores totales respectivos). + +#### GROUP BY en memoria externa {#select-group-by-in-external-memory} + +Puede habilitar el volcado de datos temporales en el disco para restringir el uso de memoria durante `GROUP BY`. +El [max\_bytes\_before\_external\_group\_by](../../operations/settings/settings.md#settings-max_bytes_before_external_group_by) determina el umbral de consumo de RAM para el dumping `GROUP BY` datos temporales al sistema de archivos. Si se establece en 0 (el valor predeterminado), está deshabilitado. + +Cuando se utiliza `max_bytes_before_external_group_by`, le recomendamos que establezca `max_memory_usage` aproximadamente el doble de alto. Esto es necesario porque hay dos etapas para la agregación: leer la fecha y formar datos intermedios (1) y fusionar los datos intermedios (2). El volcado de datos al sistema de archivos solo puede ocurrir durante la etapa 1. Si los datos temporales no se volcaron, entonces la etapa 2 puede requerir hasta la misma cantidad de memoria que en la etapa 1. + +Por ejemplo, si [Método de codificación de datos:](../../operations/settings/settings.md#settings_max_memory_usage) se estableció en 10000000000 y desea usar agregación externa, tiene sentido establecer `max_bytes_before_external_group_by` a 10000000000, y max\_memory\_usage a 20000000000. Cuando se activa la agregación externa (si hubo al menos un volcado de datos temporales), el consumo máximo de RAM es solo un poco más que `max_bytes_before_external_group_by`. + +Con el procesamiento de consultas distribuidas, la agregación externa se realiza en servidores remotos. Para que el servidor solicitante use solo una pequeña cantidad de RAM, establezca `distributed_aggregation_memory_efficient` a 1. + +Al fusionar datos en el disco, así como al fusionar resultados de servidores remotos cuando `distributed_aggregation_memory_efficient` la configuración está habilitada, consume hasta `1/256 * the_number_of_threads` de la cantidad total de RAM. + +Cuando la agregación externa está habilitada, si `max_bytes_before_external_group_by` of data (i.e. data was not flushed), the query runs just as fast as without external aggregation. If any temporary data was flushed, the run time will be several times longer (approximately three times). + +Si usted tiene un `ORDER BY` con un `LIMIT` despues `GROUP BY`, entonces la cantidad de RAM usada depende de la cantidad de datos en `LIMIT`, no en toda la tabla. Pero si el `ORDER BY` no tiene `LIMIT`, no se olvide de habilitar la clasificación externa (`max_bytes_before_external_sort`). + +### LIMITAR POR Cláusula {#limit-by-clause} + +Una consulta con el `LIMIT n BY expressions` cláusula selecciona la primera `n` para cada valor distinto de `expressions`. La clave para `LIMIT BY` puede contener cualquier número de [expresiones](../syntax.md#syntax-expressions). + +ClickHouse admite la siguiente sintaxis: + +- `LIMIT [offset_value, ]n BY expressions` +- `LIMIT n OFFSET offset_value BY expressions` + +Durante el procesamiento de consultas, ClickHouse selecciona los datos ordenados por clave de ordenación. La clave de ordenación se establece explícitamente utilizando un [ORDER BY](#select-order-by) cláusula o implícitamente como una propiedad del motor de tablas. Entonces se aplica ClickHouse `LIMIT n BY expressions` y devuelve la primera `n` filas para cada combinación distinta de `expressions`. Si `OFFSET` se especifica, a continuación, para cada bloque de datos que pertenece a una combinación distinta de `expressions`, ClickHouse salta `offset_value` número de filas desde el principio del bloque y devuelve un máximo de `n` filas como resultado. Si `offset_value` es mayor que el número de filas en el bloque de datos, ClickHouse devuelve cero filas del bloque. + +`LIMIT BY` no está relacionado con `LIMIT`. Ambos se pueden usar en la misma consulta. + +**Ejemplos** + +Tabla de muestra: + +``` sql +CREATE TABLE limit_by(id Int, val Int) ENGINE = Memory; +INSERT INTO limit_by values(1, 10), (1, 11), (1, 12), (2, 20), (2, 21); +``` + +Consulta: + +``` sql +SELECT * FROM limit_by ORDER BY id, val LIMIT 2 BY id +``` + +``` text +┌─id─┬─val─┐ +│ 1 │ 10 │ +│ 1 │ 11 │ +│ 2 │ 20 │ +│ 2 │ 21 │ +└────┴─────┘ +``` + +``` sql +SELECT * FROM limit_by ORDER BY id, val LIMIT 1, 2 BY id +``` + +``` text +┌─id─┬─val─┐ +│ 1 │ 11 │ +│ 1 │ 12 │ +│ 2 │ 21 │ +└────┴─────┘ +``` + +El `SELECT * FROM limit_by ORDER BY id, val LIMIT 2 OFFSET 1 BY id` query devuelve el mismo resultado. + +La siguiente consulta devuelve las 5 referencias principales para cada `domain, device_type` par con un máximo de 100 filas en total (`LIMIT n BY + LIMIT`). + +``` sql +SELECT + domainWithoutWWW(URL) AS domain, + domainWithoutWWW(REFERRER_URL) AS referrer, + device_type, + count() cnt +FROM hits +GROUP BY domain, referrer, device_type +ORDER BY cnt DESC +LIMIT 5 BY domain, device_type +LIMIT 100 +``` + +### Cláusula HAVING {#having-clause} + +Permite filtrar el resultado recibido después de GROUP BY, similar a la cláusula WHERE. +WHERE y HAVING difieren en que WHERE se realiza antes de la agregación (GROUP BY), mientras que HAVING se realiza después de ella. +Si no se realiza la agregación, no se puede usar HAVING. + +### ORDEN POR CLÁUSULA {#select-order-by} + +La cláusula ORDER BY contiene una lista de expresiones, a las que se puede asignar DESC o ASC (la dirección de clasificación). Si no se especifica la dirección, se supone ASC. ASC se ordena en orden ascendente y DESC en orden descendente. La dirección de ordenación se aplica a una sola expresión, no a toda la lista. Ejemplo: `ORDER BY Visits DESC, SearchPhrase` + +Para ordenar por valores de cadena, puede especificar la intercalación (comparación). Ejemplo: `ORDER BY SearchPhrase COLLATE 'tr'` - para ordenar por palabra clave en orden ascendente, utilizando el alfabeto turco, insensible a mayúsculas y minúsculas, suponiendo que las cadenas están codificadas en UTF-8. COLLATE se puede especificar o no para cada expresión en ORDER BY de forma independiente. Si se especifica ASC o DESC, se especifica COLLATE después de él. Cuando se usa COLLATE, la clasificación siempre distingue entre mayúsculas y minúsculas. + +Solo recomendamos usar COLLATE para la clasificación final de un pequeño número de filas, ya que la clasificación con COLLATE es menos eficiente que la clasificación normal por bytes. + +Las filas que tienen valores idénticos para la lista de expresiones de clasificación se generan en un orden arbitrario, que también puede ser no determinista (diferente cada vez). +Si se omite la cláusula ORDER BY, el orden de las filas tampoco está definido y también puede ser no determinista. + +`NaN` y `NULL` orden de clasificación: + +- Con el modificador `NULLS FIRST` — First `NULL`, entonces `NaN`, luego otros valores. +- Con el modificador `NULLS LAST` — First the values, then `NaN`, entonces `NULL`. +- Default — The same as with the `NULLS LAST` modificador. + +Ejemplo: + +Para la mesa + +``` text +┌─x─┬────y─┐ +│ 1 │ ᴺᵁᴸᴸ │ +│ 2 │ 2 │ +│ 1 │ nan │ +│ 2 │ 2 │ +│ 3 │ 4 │ +│ 5 │ 6 │ +│ 6 │ nan │ +│ 7 │ ᴺᵁᴸᴸ │ +│ 6 │ 7 │ +│ 8 │ 9 │ +└───┴──────┘ +``` + +Ejecute la consulta `SELECT * FROM t_null_nan ORDER BY y NULLS FIRST` conseguir: + +``` text +┌─x─┬────y─┐ +│ 1 │ ᴺᵁᴸᴸ │ +│ 7 │ ᴺᵁᴸᴸ │ +│ 1 │ nan │ +│ 6 │ nan │ +│ 2 │ 2 │ +│ 2 │ 2 │ +│ 3 │ 4 │ +│ 5 │ 6 │ +│ 6 │ 7 │ +│ 8 │ 9 │ +└───┴──────┘ +``` + +Cuando se ordenan los números de coma flotante, los NaN están separados de los otros valores. Independientemente del orden de clasificación, los NaN vienen al final. En otras palabras, para la clasificación ascendente se colocan como si fueran más grandes que todos los demás números, mientras que para la clasificación descendente se colocan como si fueran más pequeños que el resto. + +Se usa menos RAM si se especifica un LIMIT lo suficientemente pequeño además de ORDER BY. De lo contrario, la cantidad de memoria gastada es proporcional al volumen de datos para clasificar. Para el procesamiento de consultas distribuidas, si se omite GROUP BY, la ordenación se realiza parcialmente en servidores remotos y los resultados se combinan en el servidor solicitante. Esto significa que para la ordenación distribuida, el volumen de datos a ordenar puede ser mayor que la cantidad de memoria en un único servidor. + +Si no hay suficiente RAM, es posible realizar la clasificación en la memoria externa (creando archivos temporales en un disco). Utilice el ajuste `max_bytes_before_external_sort` para este propósito. Si se establece en 0 (el valor predeterminado), la ordenación externa está deshabilitada. Si está habilitada, cuando el volumen de datos a ordenar alcanza el número especificado de bytes, los datos recopilados se ordenan y se vuelcan en un archivo temporal. Después de leer todos los datos, todos los archivos ordenados se fusionan y se generan los resultados. Los archivos se escriben en el directorio /var/lib/clickhouse/tmp/ en la configuración (de forma predeterminada, pero puede ‘tmp\_path’ parámetro para cambiar esta configuración). + +La ejecución de una consulta puede usar más memoria que ‘max\_bytes\_before\_external\_sort’. Por este motivo, esta configuración debe tener un valor significativamente menor que ‘max\_memory\_usage’. Como ejemplo, si su servidor tiene 128 GB de RAM y necesita ejecutar una sola consulta, establezca ‘max\_memory\_usage’ de hasta 100 GB, y ‘max\_bytes\_before\_external\_sort’ para 80 GB. + +La clasificación externa funciona con mucha menos eficacia que la clasificación en RAM. + +### SELECT Cláusula {#select-select} + +[Expresiones](../syntax.md#syntax-expressions) especificado en el `SELECT` cláusula se calculan después de que todas las operaciones en las cláusulas descritas anteriormente hayan finalizado. Estas expresiones funcionan como si se aplicaran a filas separadas en el resultado. Si las expresiones en el `SELECT` cláusula contiene funciones agregadas, a continuación, ClickHouse procesa funciones agregadas y expresiones utilizadas como sus argumentos durante el [GROUP BY](#select-group-by-clause) agregación. + +Si desea incluir todas las columnas en el resultado, use el asterisco (`*`) simbolo. Por ejemplo, `SELECT * FROM ...`. + +Para hacer coincidir algunas columnas en el resultado con un [Re2](https://en.wikipedia.org/wiki/RE2_(software)) expresión regular, puede utilizar el `COLUMNS` expresion. + +``` sql +COLUMNS('regexp') +``` + +Por ejemplo, considere la tabla: + +``` sql +CREATE TABLE default.col_names (aa Int8, ab Int8, bc Int8) ENGINE = TinyLog +``` + +La siguiente consulta selecciona datos de todas las columnas que contienen `a` símbolo en su nombre. + +``` sql +SELECT COLUMNS('a') FROM col_names +``` + +``` text +┌─aa─┬─ab─┐ +│ 1 │ 1 │ +└────┴────┘ +``` + +Las columnas seleccionadas no se devuelven en orden alfabético. + +Puede utilizar múltiples `COLUMNS` expresiones en una consulta y aplicarles funciones. + +Por ejemplo: + +``` sql +SELECT COLUMNS('a'), COLUMNS('c'), toTypeName(COLUMNS('c')) FROM col_names +``` + +``` text +┌─aa─┬─ab─┬─bc─┬─toTypeName(bc)─┐ +│ 1 │ 1 │ 1 │ Int8 │ +└────┴────┴────┴────────────────┘ +``` + +Cada columna devuelta por el `COLUMNS` expresión se pasa a la función como un argumento separado. También puede pasar otros argumentos a la función si los admite. Tenga cuidado al usar funciones. Si una función no admite la cantidad de argumentos que le ha pasado, ClickHouse lanza una excepción. + +Por ejemplo: + +``` sql +SELECT COLUMNS('a') + COLUMNS('c') FROM col_names +``` + +``` text +Received exception from server (version 19.14.1): +Code: 42. DB::Exception: Received from localhost:9000. DB::Exception: Number of arguments for function plus doesn't match: passed 3, should be 2. +``` + +En este ejemplo, `COLUMNS('a')` devuelve dos columnas: `aa` y `ab`. `COLUMNS('c')` devuelve el `bc` columna. El `+` el operador no puede aplicar a 3 argumentos, por lo que ClickHouse lanza una excepción con el mensaje relevante. + +Columnas que coinciden con el `COLUMNS` expresión puede tener diferentes tipos de datos. Si `COLUMNS` no coincide con ninguna columna y es la única expresión en `SELECT`, ClickHouse lanza una excepción. + +### Cláusula DISTINCT {#select-distinct} + +Si se especifica DISTINCT, sólo quedará una sola fila de todos los conjuntos de filas totalmente coincidentes en el resultado. +El resultado será el mismo que si GROUP BY se especificara en todos los campos especificados en SELECT sin funciones agregadas. Pero hay varias diferencias con GROUP BY: + +- DISTINCT se puede aplicar junto con GROUP BY. +- Cuando ORDER BY se omite y se define LIMIT, la consulta deja de ejecutarse inmediatamente después de leer el número necesario de filas diferentes. +- Los bloques de datos se generan a medida que se procesan, sin esperar a que finalice la ejecución de toda la consulta. + +DISTINCT no se admite si SELECT tiene al menos una columna de matriz. + +`DISTINCT` trabaja con [NULL](../syntax.md) como si `NULL` Era un valor específico, y `NULL=NULL`. En otras palabras, en el `DISTINCT` resultados, diferentes combinaciones con `NULL` sólo ocurren una vez. + +ClickHouse admite el uso de `DISTINCT` y `ORDER BY` para diferentes columnas en una consulta. El `DISTINCT` cláusula se ejecuta antes de `ORDER BY` clausula. + +Tabla de ejemplo: + +``` text +┌─a─┬─b─┐ +│ 2 │ 1 │ +│ 1 │ 2 │ +│ 3 │ 3 │ +│ 2 │ 4 │ +└───┴───┘ +``` + +Al seleccionar datos con el `SELECT DISTINCT a FROM t1 ORDER BY b ASC` consulta, obtenemos el siguiente resultado: + +``` text +┌─a─┐ +│ 2 │ +│ 1 │ +│ 3 │ +└───┘ +``` + +Si cambiamos la dirección de clasificación `SELECT DISTINCT a FROM t1 ORDER BY b DESC`, obtenemos el siguiente resultado: + +``` text +┌─a─┐ +│ 3 │ +│ 1 │ +│ 2 │ +└───┘ +``` + +Fila `2, 4` se cortó antes de clasificar. + +Tenga en cuenta esta especificidad de implementación al programar consultas. + +### Cláusula LIMIT {#limit-clause} + +`LIMIT m` permite seleccionar la primera `m` filas del resultado. + +`LIMIT n, m` permite seleccionar la primera `m` el resultado después de omitir la primera `n` filas. El `LIMIT m OFFSET n` sintaxis también es compatible. + +`n` y `m` deben ser enteros no negativos. + +Si no hay una `ORDER BY` cláusula que ordena explícitamente los resultados, el resultado puede ser arbitrario y no determinista. + +### UNION ALL Cláusula {#union-all-clause} + +Puede utilizar UNION ALL para combinar cualquier número de consultas. Ejemplo: + +``` sql +SELECT CounterID, 1 AS table, toInt64(count()) AS c + FROM test.hits + GROUP BY CounterID + +UNION ALL + +SELECT CounterID, 2 AS table, sum(Sign) AS c + FROM test.visits + GROUP BY CounterID + HAVING c > 0 +``` + +Solo se admite UNION ALL. La UNIÓN regular (UNION DISTINCT) no es compatible. Si necesita UNION DISTINCT, puede escribir SELECT DISTINCT desde una subconsulta que contenga UNION ALL. + +Las consultas que forman parte de UNION ALL se pueden ejecutar simultáneamente y sus resultados se pueden mezclar. + +La estructura de los resultados (el número y el tipo de columnas) debe coincidir con las consultas. Pero los nombres de columna pueden diferir. En este caso, los nombres de columna para el resultado final se tomarán de la primera consulta. La fundición de tipo se realiza para uniones. Por ejemplo, si dos consultas que se combinan tienen el mismo campo-`Nullable` y `Nullable` tipos de un tipo compatible, el resultado `UNION ALL` tiene una `Nullable` campo de tipo. + +Las consultas que forman parte de UNION ALL no se pueden encerrar entre paréntesis. ORDER BY y LIMIT se aplican a consultas separadas, no al resultado final. Si necesita aplicar una conversión al resultado final, puede colocar todas las consultas con UNION ALL en una subconsulta en la cláusula FROM. + +### INTO OUTFILE Cláusula {#into-outfile-clause} + +Añadir el `INTO OUTFILE filename` cláusula (donde filename es un literal de cadena) para redirigir la salida de la consulta al archivo especificado. +A diferencia de MySQL, el archivo se crea en el lado del cliente. La consulta fallará si ya existe un archivo con el mismo nombre de archivo. +Esta funcionalidad está disponible en el cliente de línea de comandos y clickhouse-local (una consulta enviada a través de la interfaz HTTP fallará). + +El formato de salida predeterminado es TabSeparated (el mismo que en el modo de lote de cliente de línea de comandos). + +### FORMAT Cláusula {#format-clause} + +Especificar ‘FORMAT format’ para obtener datos en cualquier formato especificado. +Puede usar esto por conveniencia o para crear volcados. +Para obtener más información, consulte la sección “Formats”. +Si se omite la cláusula FORMAT, se utiliza el formato predeterminado, que depende tanto de la configuración como de la interfaz utilizada para acceder a la base de datos. Para la interfaz HTTP y el cliente de línea de comandos en modo por lotes, el formato predeterminado es TabSeparated. Para el cliente de línea de comandos en modo interactivo, el formato predeterminado es PrettyCompact (tiene tablas atractivas y compactas). + +Cuando se utiliza el cliente de línea de comandos, los datos se pasan al cliente en un formato interno eficiente. El cliente interpreta independientemente la cláusula FORMAT de la consulta y da formato a los datos en sí (aliviando así la red y el servidor de la carga). + +### IN Operadores {#select-in-operators} + +El `IN`, `NOT IN`, `GLOBAL IN`, y `GLOBAL NOT IN` están cubiertos por separado, ya que su funcionalidad es bastante rica. + +El lado izquierdo del operador es una sola columna o una tupla. + +Ejemplos: + +``` sql +SELECT UserID IN (123, 456) FROM ... +SELECT (CounterID, UserID) IN ((34, 123), (101500, 456)) FROM ... +``` + +Si el lado izquierdo es una sola columna que está en el índice, y el lado derecho es un conjunto de constantes, el sistema usa el índice para procesar la consulta. + +Don't list too many values explicitly (i.e. millions). If a data set is large, put it in a temporary table (for example, see the section “External data for query processing”), luego use una subconsulta. + +El lado derecho del operador puede ser un conjunto de expresiones constantes, un conjunto de tuplas con expresiones constantes (mostradas en los ejemplos anteriores) o el nombre de una tabla de base de datos o subconsulta SELECT entre paréntesis. + +Si el lado derecho del operador es el nombre de una tabla (por ejemplo, `UserID IN users`), esto es equivalente a la subconsulta `UserID IN (SELECT * FROM users)`. Úselo cuando trabaje con datos externos que se envían junto con la consulta. Por ejemplo, la consulta se puede enviar junto con un conjunto de ID de usuario ‘users’ tabla temporal, que debe ser filtrada. + +Si el lado derecho del operador es un nombre de tabla que tiene el motor Set (un conjunto de datos preparado que siempre está en RAM), el conjunto de datos no se volverá a crear para cada consulta. + +La subconsulta puede especificar más de una columna para filtrar tuplas. +Ejemplo: + +``` sql +SELECT (CounterID, UserID) IN (SELECT CounterID, UserID FROM ...) FROM ... +``` + +Las columnas a la izquierda y a la derecha del operador IN deben tener el mismo tipo. + +El operador IN y la subconsulta pueden aparecer en cualquier parte de la consulta, incluidas las funciones agregadas y las funciones lambda. +Ejemplo: + +``` sql +SELECT + EventDate, + avg(UserID IN + ( + SELECT UserID + FROM test.hits + WHERE EventDate = toDate('2014-03-17') + )) AS ratio +FROM test.hits +GROUP BY EventDate +ORDER BY EventDate ASC +``` + +``` text +┌──EventDate─┬────ratio─┐ +│ 2014-03-17 │ 1 │ +│ 2014-03-18 │ 0.807696 │ +│ 2014-03-19 │ 0.755406 │ +│ 2014-03-20 │ 0.723218 │ +│ 2014-03-21 │ 0.697021 │ +│ 2014-03-22 │ 0.647851 │ +│ 2014-03-23 │ 0.648416 │ +└────────────┴──────────┘ +``` + +Para cada día después del 17 de marzo, cuente el porcentaje de páginas vistas realizadas por los usuarios que visitaron el sitio el 17 de marzo. +Una subconsulta en la cláusula IN siempre se ejecuta una sola vez en un único servidor. No hay subconsultas dependientes. + +#### Procesamiento NULL {#null-processing-1} + +Durante el procesamiento de la solicitud, el operador IN asume que el resultado de una operación [NULL](../syntax.md) siempre es igual a `0`, independientemente de si `NULL` está en el lado derecho o izquierdo del operador. `NULL` Los valores no se incluyen en ningún conjunto de datos, no se corresponden entre sí y no se pueden comparar. + +Aquí hay un ejemplo con el `t_null` tabla: + +``` text +┌─x─┬────y─┐ +│ 1 │ ᴺᵁᴸᴸ │ +│ 2 │ 3 │ +└───┴──────┘ +``` + +Ejecución de la consulta `SELECT x FROM t_null WHERE y IN (NULL,3)` da el siguiente resultado: + +``` text +┌─x─┐ +│ 2 │ +└───┘ +``` + +Se puede ver que la fila en la que `y = NULL` se expulsa de los resultados de la consulta. Esto se debe a que ClickHouse no puede decidir si `NULL` está incluido en el `(NULL,3)` conjunto, devuelve `0` como resultado de la operación, y `SELECT` excluye esta fila de la salida final. + +``` sql +SELECT y IN (NULL, 3) +FROM t_null +``` + +``` text +┌─in(y, tuple(NULL, 3))─┐ +│ 0 │ +│ 1 │ +└───────────────────────┘ +``` + +#### Subconsultas distribuidas {#select-distributed-subqueries} + +Hay dos opciones para IN-s con subconsultas (similar a JOINs): normal `IN` / `JOIN` y `GLOBAL IN` / `GLOBAL JOIN`. Se diferencian en cómo se ejecutan para el procesamiento de consultas distribuidas. + +!!! attention "Atención" + Recuerde que los algoritmos descritos a continuación pueden funcionar de manera diferente dependiendo de la [configuración](../../operations/settings/settings.md) `distributed_product_mode` configuración. + +Cuando se utiliza el IN normal, la consulta se envía a servidores remotos, y cada uno de ellos ejecuta las subconsultas en el `IN` o `JOIN` clausula. + +Cuando se utiliza `GLOBAL IN` / `GLOBAL JOINs`, primero todas las subconsultas se ejecutan para `GLOBAL IN` / `GLOBAL JOINs`, y los resultados se recopilan en tablas temporales. A continuación, las tablas temporales se envían a cada servidor remoto, donde las consultas se ejecutan utilizando estos datos temporales. + +Para una consulta no distribuida, utilice el `IN` / `JOIN`. + +Tenga cuidado al usar subconsultas en el `IN` / `JOIN` para el procesamiento de consultas distribuidas. + +Veamos algunos ejemplos. Supongamos que cada servidor del clúster tiene un **local\_table**. Cada servidor también tiene un **distributed\_table** mesa con el **Distribuido** tipo, que mira todos los servidores del clúster. + +Para una consulta al **distributed\_table**, la consulta se enviará a todos los servidores remotos y se ejecutará en ellos usando el **local\_table**. + +Por ejemplo, la consulta + +``` sql +SELECT uniq(UserID) FROM distributed_table +``` + +se enviará a todos los servidores remotos como + +``` sql +SELECT uniq(UserID) FROM local_table +``` + +y ejecutar en cada uno de ellos en paralelo, hasta que llegue a la etapa donde se pueden combinar resultados intermedios. Luego, los resultados intermedios se devolverán al servidor solicitante y se fusionarán en él, y el resultado final se enviará al cliente. + +Ahora examinemos una consulta con IN: + +``` sql +SELECT uniq(UserID) FROM distributed_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM local_table WHERE CounterID = 34) +``` + +- Cálculo de la intersección de audiencias de dos sitios. + +Esta consulta se enviará a todos los servidores remotos como + +``` sql +SELECT uniq(UserID) FROM local_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM local_table WHERE CounterID = 34) +``` + +En otras palabras, los datos establecidos en la cláusula IN se recopilarán en cada servidor de forma independiente, solo a través de los datos que se almacenan localmente en cada uno de los servidores. + +Esto funcionará correctamente y de manera óptima si está preparado para este caso y ha distribuido datos en los servidores de clúster de modo que los datos de un único ID de usuario residen completamente en un único servidor. En este caso, todos los datos necesarios estarán disponibles localmente en cada servidor. De lo contrario, el resultado será inexacto. Nos referimos a esta variación de la consulta como “local IN”. + +Para corregir cómo funciona la consulta cuando los datos se distribuyen aleatoriamente entre los servidores de clúster, puede especificar **distributed\_table** dentro de una subconsulta. La consulta se vería así: + +``` sql +SELECT uniq(UserID) FROM distributed_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM distributed_table WHERE CounterID = 34) +``` + +Esta consulta se enviará a todos los servidores remotos como + +``` sql +SELECT uniq(UserID) FROM local_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM distributed_table WHERE CounterID = 34) +``` + +La subconsulta comenzará a ejecutarse en cada servidor remoto. Dado que la subconsulta utiliza una tabla distribuida, la subconsulta que se encuentra en cada servidor remoto se reenviará a cada servidor remoto como + +``` sql +SELECT UserID FROM local_table WHERE CounterID = 34 +``` + +Por ejemplo, si tiene un clúster de 100 servidores, la ejecución de toda la consulta requerirá 10.000 solicitudes elementales, lo que generalmente se considera inaceptable. + +En tales casos, siempre debe usar GLOBAL IN en lugar de IN. Veamos cómo funciona para la consulta + +``` sql +SELECT uniq(UserID) FROM distributed_table WHERE CounterID = 101500 AND UserID GLOBAL IN (SELECT UserID FROM distributed_table WHERE CounterID = 34) +``` + +El servidor del solicitante ejecutará la subconsulta + +``` sql +SELECT UserID FROM distributed_table WHERE CounterID = 34 +``` + +y el resultado se colocará en una tabla temporal en la RAM. A continuación, la solicitud se enviará a cada servidor remoto como + +``` sql +SELECT uniq(UserID) FROM local_table WHERE CounterID = 101500 AND UserID GLOBAL IN _data1 +``` + +y la tabla temporal `_data1` se enviará a cada servidor remoto con la consulta (el nombre de la tabla temporal está definido por la implementación). + +Esto es más óptimo que usar el IN normal. Sin embargo, tenga en cuenta los siguientes puntos: + +1. Al crear una tabla temporal, los datos no se hacen únicos. Para reducir el volumen de datos transmitidos a través de la red, especifique DISTINCT en la subconsulta. (No necesita hacer esto para un IN normal.) +2. La tabla temporal se enviará a todos los servidores remotos. La transmisión no tiene en cuenta la topología de red. Por ejemplo, si 10 servidores remotos residen en un centro de datos que es muy remoto en relación con el servidor solicitante, los datos se enviarán 10 veces a través del canal al centro de datos remoto. Intente evitar grandes conjuntos de datos cuando use GLOBAL IN. +3. Al transmitir datos a servidores remotos, las restricciones en el ancho de banda de la red no son configurables. Puede sobrecargar la red. +4. Intente distribuir datos entre servidores para que no necesite usar GLOBAL IN de forma regular. +5. Si necesita utilizar GLOBAL IN con frecuencia, planifique la ubicación del clúster ClickHouse para que un único grupo de réplicas resida en no más de un centro de datos con una red rápida entre ellos, de modo que una consulta se pueda procesar completamente dentro de un único centro de datos. + +También tiene sentido especificar una tabla local en el `GLOBAL IN` cláusula, en caso de que esta tabla local solo esté disponible en el servidor solicitante y desee usar datos de ella en servidores remotos. + +### Valores extremos {#extreme-values} + +Además de los resultados, también puede obtener valores mínimos y máximos para las columnas de resultados. Para hacer esto, establezca el **extremo** a 1. Los mínimos y máximos se calculan para tipos numéricos, fechas y fechas con horas. Para otras columnas, se generan los valores predeterminados. + +An extra two rows are calculated – the minimums and maximums, respectively. These extra two rows are output in `JSON*`, `TabSeparated*`, y `Pretty*` [formato](../../interfaces/formats.md), separado de las otras filas. No se emiten para otros formatos. + +En `JSON*` los valores extremos se emiten en un formato separado. ‘extremes’ campo. En `TabSeparated*` , la fila viene después del resultado principal, y después de ‘totals’ si está presente. Está precedido por una fila vacía (después de los otros datos). En `Pretty*` formatea, la fila se muestra como una tabla separada después del resultado principal, y después de `totals` si está presente. + +Los valores extremos se calculan para las filas anteriores `LIMIT`, pero después `LIMIT BY`. Sin embargo, cuando se usa `LIMIT offset, size`, las filas antes `offset` están incluidos en `extremes`. En las solicitudes de secuencia, el resultado también puede incluir un pequeño número de filas que pasaron por `LIMIT`. + +### Nota {#notes} + +El `GROUP BY` y `ORDER BY` las cláusulas no admiten argumentos posicionales. Esto contradice MySQL, pero se ajusta al SQL estándar. +Por ejemplo, `GROUP BY 1, 2` will be interpreted as grouping by constants (i.e. aggregation of all rows into one). + +Puedes usar sinónimos (`AS` aliases) en cualquier parte de una consulta. + +Puede poner un asterisco en cualquier parte de una consulta en lugar de una expresión. Cuando se analiza la consulta, el asterisco se expande a una lista de todas las columnas de la tabla `MATERIALIZED` y `ALIAS` columna). Solo hay unos pocos casos en los que se justifica el uso de un asterisco: + +- Al crear un volcado de tabla. +- Para tablas que contienen solo unas pocas columnas, como las tablas del sistema. +- Para obtener información sobre qué columnas están en una tabla. En este caso, establezca `LIMIT 1`. Pero es mejor usar el `DESC TABLE` consulta. +- Cuando hay una filtración fuerte en un pequeño número de columnas usando `PREWHERE`. +- En subconsultas (ya que las columnas que no son necesarias para la consulta externa están excluidas de las subconsultas). + +En todos los demás casos, no recomendamos usar el asterisco, ya que solo le da los inconvenientes de un DBMS columnar en lugar de las ventajas. En otras palabras, no se recomienda usar el asterisco. + +[Artículo Original](https://clickhouse.tech/docs/en/query_language/select/) diff --git a/docs/fa/sql-reference/statements/select.md b/docs/fa/sql-reference/statements/select.md index 285f8acf473..41ddbb0f772 100644 --- a/docs/fa/sql-reference/statements/select.md +++ b/docs/fa/sql-reference/statements/select.md @@ -1,6 +1,6 @@ --- machine_translated: true -machine_translated_rev: d734a8e46ddd7465886ba4133bff743c55190626 +machine_translated_rev: 0f7ef7704d018700049223525bad4a63911b6e70 toc_priority: 33 toc_title: SELECT --- @@ -31,7 +31,7 @@ SELECT [DISTINCT] expr_list همه بند اختیاری هستند, به جز برای لیست مورد نیاز از عبارات بلافاصله پس از انتخاب. بند های زیر تقریبا به همان ترتیب در نوار نقاله اجرای پرس و جو توصیف می شوند. -اگر پرس و جو حذف `DISTINCT`, `GROUP BY` و `ORDER BY` بند و `IN` و `JOIN` subqueries این پرس و جو خواهد شد به طور کامل جریان پردازش با استفاده از O(1) میزان رم. +اگر پرس و جو حذف `DISTINCT`, `GROUP BY` و `ORDER BY` بند و `IN` و `JOIN` کارخانه های فرعی, پرس و جو خواهد شد به طور کامل جریان پردازش, با استفاده از ای(1) مقدار رم. در غیر این صورت, پرس و جو ممکن است مقدار زیادی از رم مصرف اگر محدودیت های مناسب مشخص نشده است: `max_memory_usage`, `max_rows_to_group_by`, `max_rows_to_sort`, `max_rows_in_distinct`, `max_bytes_in_distinct`, `max_rows_in_set`, `max_bytes_in_set`, `max_rows_in_join`, `max_bytes_in_join`, `max_bytes_before_external_sort`, `max_bytes_before_external_group_by`. برای کسب اطلاعات بیشتر به بخش مراجعه کنید “Settings”. ممکن است که به استفاده از مرتب سازی خارجی (صرفه جویی در جداول موقت به یک دیسک) و تجمع خارجی. `The system does not have "merge join"`. ### با بند {#with-clause} @@ -65,7 +65,7 @@ GROUP BY table ORDER BY s ``` -مثال 3: استفاده از نتایج عددی پرس +مثال 3: با استفاده از نتایج حاصل از زیرخاکری اسکالر ``` sql /* this example would return TOP 10 of most huge tables */ @@ -85,7 +85,7 @@ LIMIT 10 ``` مثال 4: استفاده مجدد از بیان در زیرخاکری -به عنوان یک راهحل برای محدودیت کنونی برای بیان استفاده در subqueries شما ممکن است تکراری است. +به عنوان یک راه حل برای محدودیت فعلی برای استفاده بیان در زیر مجموعه, شما ممکن است تکراری. ``` sql WITH ['hello'] AS hello @@ -149,7 +149,7 @@ FROM - هنگامی که شما شرایط زمان بندی دقیق (مانند \<100 مگابایت) اما شما نمی توانید هزینه منابع سخت افزاری اضافی را برای دیدار با خود توجیه کنید. - هنگامی که داده های خام خود را دقیق نیست, بنابراین تقریب می کند به طرز محسوسی کاهش کیفیت. -- نیازهای کسب و کار هدف تقریبی نتایج (برای مقرون به صرفه بودن و یا به منظور به بازار دقیق نتایج به کاربران حق بیمه). +- کسب و کار مورد نیاز هدف قرار دادن نتایج تقریبی (برای مقرون به صرفه بودن, و یا به منظور بازار نتایج دقیق به کاربران حق بیمه). !!! note "یادداشت" شما فقط می توانید نمونه برداری با استفاده از جداول در [ادغام](../../engines/table-engines/mergetree-family/mergetree.md) خانواده, و تنها در صورتی که بیان نمونه برداری در ایجاد جدول مشخص شد (دیدن [موتور ادغام](../../engines/table-engines/mergetree-family/mergetree.md#table_engine-mergetree-creating-a-table)). @@ -250,7 +250,7 @@ SAMPLE 1/10 OFFSET 1/2 ### مجموعه پیوستن بند {#select-array-join-clause} -اجازه می دهد تا اجرای `JOIN` با یک آرایه یا تو در تو ساختار داده ها. قصد این است که شبیه به [ارریجین](../../sql-reference/functions/array-join.md#functions_arrayjoin) تابع, اما قابلیت های خود را گسترده تر است. +اجازه می دهد تا اجرای `JOIN` با یک مجموعه یا ساختار داده های تو در تو. قصد شبیه به است [ارریجین](../functions/array-join.md#functions_arrayjoin) تابع, اما قابلیت های خود را گسترده تر است. ``` sql SELECT @@ -604,7 +604,776 @@ USING (equi_column1, ... equi_columnN, asof_column) مثلا, جداول زیر را در نظر بگیرید: -"’متن -table\_1 table\_2 + table_1 table_2 + event | ev_time | user_id event | ev_time | user_id + ----------|---------|---------- ----------|---------|---------- + ... ... + event_1_1 | 12:00 | 42 event_2_1 | 11:59 | 42 + ... event_2_2 | 12:30 | 42 + event_1_2 | 13:00 | 42 event_2_3 | 13:00 | 42 + ... ... -رویداد \| عصر / رویداد فراسوی / عصر / شناسه +`ASOF JOIN` می توانید برچسب زمان از یک رویداد کاربر از را `table_1` و پیدا کردن یک رویداد در `table_2` جایی که برچسب زمان نزدیک به زمان این رویداد از `table_1` مربوط به نزدیک ترین شرایط بازی. مقادیر برچسب زمان برابر نزدیک ترین در صورت موجود بودن. اینجا `user_id` ستون را می توان برای پیوستن به برابری و `ev_time` ستون را می توان برای پیوستن به در نزدیک ترین بازی استفاده می شود. در مثال ما, `event_1_1` می توان با پیوست `event_2_1` و `event_1_2` می توان با پیوست `event_2_3` اما `event_2_2` نمیشه عضو شد + +!!! note "یادداشت" + `ASOF` پیوستن است **نه** پردازشگر پشتیبانی شده: [پیوستن](../../engines/table-engines/special/join.md) موتور جدول. + +برای تنظیم مقدار سختگیرانه پیش فرض, استفاده از پارامتر پیکربندی جلسه [بررسی اجمالی](../../operations/settings/settings.md#settings-join_default_strictness). + +#### GLOBAL JOIN {#global-join} + +هنگام استفاده از نرمال `JOIN` پرس و جو به سرورهای راه دور ارسال می شود. زیرکریزها روی هر کدام اجرا می شوند تا میز مناسب را بسازند و پیوستن با این جدول انجام می شود. به عبارت دیگر, جدول سمت راست بر روی هر سرور تشکیل به طور جداگانه. + +هنگام استفاده از `GLOBAL ... JOIN`, اول سرور درخواست کننده اجرا می شود یک خرده فروشی برای محاسبه جدول سمت راست. این جدول موقت به هر سرور از راه دور منتقل می شود و نمایش داده می شود با استفاده از داده های موقت منتقل می شود. + +مراقب باشید در هنگام استفاده از `GLOBAL`. برای کسب اطلاعات بیشتر به بخش مراجعه کنید [توزیع subqueries](#select-distributed-subqueries). + +#### توصیه های استفاده {#usage-recommendations} + +هنگامی که در حال اجرا `JOIN` بهینه سازی سفارش اعدام در رابطه با سایر مراحل پرس و جو وجود ندارد. پیوستن (جستجو در جدول سمت راست) قبل از فیلتر کردن در اجرا می شود `WHERE` و قبل از تجمع. به منظور صراحت تنظیم سفارش پردازش, توصیه می کنیم در حال اجرا یک `JOIN` خرده فروشی با یک خرده فروشی. + +مثال: + +``` sql +SELECT + CounterID, + hits, + visits +FROM +( + SELECT + CounterID, + count() AS hits + FROM test.hits + GROUP BY CounterID +) ANY LEFT JOIN +( + SELECT + CounterID, + sum(Sign) AS visits + FROM test.visits + GROUP BY CounterID +) USING CounterID +ORDER BY hits DESC +LIMIT 10 +``` + +``` text +┌─CounterID─┬───hits─┬─visits─┐ +│ 1143050 │ 523264 │ 13665 │ +│ 731962 │ 475698 │ 102716 │ +│ 722545 │ 337212 │ 108187 │ +│ 722889 │ 252197 │ 10547 │ +│ 2237260 │ 196036 │ 9522 │ +│ 23057320 │ 147211 │ 7689 │ +│ 722818 │ 90109 │ 17847 │ +│ 48221 │ 85379 │ 4652 │ +│ 19762435 │ 77807 │ 7026 │ +│ 722884 │ 77492 │ 11056 │ +└───────────┴────────┴────────┘ +``` + +زیرمجموعه ها به شما اجازه نمی دهند نام ها را تنظیم کنید یا از یک ستون از یک زیر اندازه خاص استفاده کنید. +ستون های مشخص شده در `USING` باید نام های مشابه در هر دو کارخانه های فرعی دارند, و ستون های دیگر باید متفاوت به نام. شما می توانید نام مستعار برای تغییر نام ستون در زیرکریز استفاده (به عنوان مثال با استفاده از نام مستعار `hits` و `visits`). + +این `USING` بند یک یا چند ستون برای پیوستن به مشخص, که ایجاد برابری این ستون. لیست ستون ها بدون براکت تنظیم شده است. شرایط پیوستن پیچیده تر پشتیبانی نمی شوند. + +جدول سمت راست (نتیجه زیرخاکی) ساکن در رم. اگر حافظه کافی وجود ندارد, شما می توانید یک اجرا کنید `JOIN`. + +هر بار که پرس و جو با همان اجرا شود `JOIN`, خرده فروشی است دوباره اجرا به دلیل نتیجه ذخیره سازی نیست. برای جلوگیری از این, استفاده از ویژه [پیوستن](../../engines/table-engines/special/join.md) موتور جدول, که مجموعه ای تهیه شده برای پیوستن است که همیشه در رم. + +در بعضی موارد کارایی بیشتری برای استفاده دارد `IN` به جای `JOIN`. +در میان انواع مختلف `JOIN`, موثر ترین است `ANY LEFT JOIN` پس `ANY INNER JOIN`. کمترین کارایی عبارتند از `ALL LEFT JOIN` و `ALL INNER JOIN`. + +اگر شما نیاز به یک `JOIN` برای پیوستن به جداول بعد (این جداول نسبتا کوچک است که شامل خواص ابعاد هستند, مانند نام برای کمپین های تبلیغاتی), یک `JOIN` ممکن است بسیار مناسب با توجه به این واقعیت است که جدول سمت راست برای هر پرس و جو دوباره قابل دسترسی است. برای چنین مواردی وجود دارد “external dictionaries” ویژگی است که شما باید به جای استفاده از `JOIN`. برای کسب اطلاعات بیشتر به بخش مراجعه کنید [واژهنامهها خارجی](../dictionaries/external-dictionaries/external-dicts.md). + +**محدودیت حافظه** + +تاتر با استفاده از [هش پیوستن](https://en.wikipedia.org/wiki/Hash_join) الگوریتم. تاتر طول می کشد `` و یک جدول هش را در رم ایجاد می کند. اگر شما نیاز به محدود کردن پیوستن به مصرف حافظه عملیات استفاده از تنظیمات زیر: + +- [\_پاک کردن \_روشن گرافیک](../../operations/settings/query-complexity.md#settings-max_rows_in_join) — Limits number of rows in the hash table. +- [\_پویش همیشگی](../../operations/settings/query-complexity.md#settings-max_bytes_in_join) — Limits size of the hash table. + +هنگامی که هر یک از این محدودیت رسیده است, کلیک به عنوان عمل می کند [\_شروع مجدد](../../operations/settings/query-complexity.md#settings-join_overflow_mode) تنظیم دستور. + +#### پردازش سلولهای خالی یا خالی {#processing-of-empty-or-null-cells} + +در حالی که پیوستن به جداول سلول های خالی ظاهر می شود. تنظیمات [ارزشهای خبری عبارتند از:](../../operations/settings/settings.md#join_use_nulls) تعریف چگونه خانه را پر می کند این سلول ها. + +اگر `JOIN` کلید ها [Nullable](../data-types/nullable.md) زمینه, ردیف که حداقل یکی از کلید های دارای ارزش [NULL](../syntax.md#null-literal) عضو نشده. + +#### محدودیت نحو {#syntax-limitations} + +برای چند `JOIN` بند در یک `SELECT` پرسوجو: + +- گرفتن تمام ستون ها از طریق `*` در دسترس است تنها اگر جداول پیوست, نمی فرعی. +- این `PREWHERE` بند در دسترس نیست. + +برای `ON`, `WHERE` و `GROUP BY` بند: + +- عبارات دلخواه را نمی توان در `ON`, `WHERE` و `GROUP BY` بند, اما شما می توانید یک عبارت در یک تعریف `SELECT` بند و سپس در این بند از طریق یک نام مستعار استفاده کنید. + +### بند کجا {#select-where} + +در صورتی که بند جایی وجود دارد, باید بیان با نوع زیرپوش شامل8. این است که معمولا بیان با مقایسه و اپراتورهای منطقی. +این عبارت خواهد شد برای فیلتر کردن داده ها قبل از همه تحولات دیگر استفاده می شود. + +اگر شاخص توسط موتور جدول پایگاه داده پشتیبانی, بیان بر توانایی استفاده از شاخص ارزیابی. + +### در بند {#prewhere-clause} + +این بند همان معنی که بند است. تفاوت در این است که داده ها از جدول خوانده می شوند. +هنگامی که با استفاده از PREWHERE اول تنها ستون لازم برای اجرای PREWHERE در حال خواندن. سپس ستون های دیگر خوانده می شوند که برای اجرای پرس و جو مورد نیاز است اما تنها بلوک هایی که بیان پیشین درست است. + +این را حس می کند به استفاده از همه جا اگر شرایط فیلتراسیون که توسط یک اقلیت از ستون ها در پرس و جو استفاده می شود وجود دارد, اما که فیلتراسیون داده های قوی. این باعث کاهش حجم داده ها به خواندن. + +مثلا, مفید است برای نوشتن از کجا برای نمایش داده شد که استخراج تعداد زیادی از ستون, اما این تنها فیلتراسیون برای چند ستون دارند. + +همه جا تنها با جداول از پشتیبانی `*MergeTree` خانواده + +یک پرس و جو ممکن است به طور همزمان مشخص PREWHERE و در آن. در این مورد PREWHERE پیش می آید که در آن. + +اگر ‘optimize\_move\_to\_prewhere’ تنظیم به 1 و PREWHERE حذف شده از سیستم با استفاده از ابتکارات به طور خودکار حرکت قطعات از عبارات از کجا PREWHERE. + +### گروه بر اساس بند {#select-group-by-clause} + +این یکی از مهم ترین بخش های سندرم تونل کارپ ستون گرا است. + +در صورتی که یک گروه بند وجود دارد, باید یک لیست از عبارات حاوی. هر عبارت خواهد شد به اینجا به عنوان یک اشاره “key”. +همه عبارات در انتخاب, داشتن, و سفارش توسط بند باید از کلید و یا از توابع کل محاسبه می شود. به عبارت دیگر, هر ستون انتخاب شده از جدول باید یا در کلید و یا در داخل توابع دانه استفاده می شود. + +اگر یک پرس و جو شامل تنها ستون جدول در داخل توابع کل, گروه بند را می توان حذف, و تجمع توسط یک مجموعه خالی از کلید فرض بر این است. + +مثال: + +``` sql +SELECT + count(), + median(FetchTiming > 60 ? 60 : FetchTiming), + count() - sum(Refresh) +FROM hits +``` + +با این حال, در مقابل به استاندارد گذاشتن, اگر جدول هیچ ردیف ندارد (یا هیچ در همه وجود ندارد, و یا هر پس از استفاده از جایی که برای فیلتر کردن وجود ندارد), یک نتیجه خالی بازگشته است, و نه در نتیجه از یکی از ردیف های حاوی مقادیر اولیه از توابع کل. + +همانطور که به خروجی زیر مخالف (و منطبق با استاندارد گذاشتن), شما می توانید برخی از ارزش برخی از ستون است که در یک کلید و یا کل تابع نیست (به جز عبارات ثابت). برای کار در اطراف این, شما می توانید با استفاده از ‘any’ تابع جمع (اولین مقدار مواجه می شوند) یا ‘min/max’. + +مثال: + +``` sql +SELECT + domainWithoutWWW(URL) AS domain, + count(), + any(Title) AS title -- getting the first occurred page header for each domain. +FROM hits +GROUP BY domain +``` + +برای هر مقدار کلیدی مختلف مواجه می شوند, گروه با محاسبه مجموعه ای از مقادیر تابع کل. + +گروه توسط ستون های مجموعه پشتیبانی نمی شود. + +ثابت را نمی توان به عنوان استدلال برای توابع کل مشخص شده است. مثال: مجموع(1). به جای این, شما می توانید از ثابت خلاص. مثال: `count()`. + +#### پردازش پوچ {#null-processing} + +برای گروه بندی, تفسیر کلیک [NULL](../syntax.md) به عنوان یک ارزش, و `NULL=NULL`. + +در اینجا یک مثال برای نشان دادن این بدان معنی است. + +فرض کنید شما باید این جدول: + +``` text +┌─x─┬────y─┐ +│ 1 │ 2 │ +│ 2 │ ᴺᵁᴸᴸ │ +│ 3 │ 2 │ +│ 3 │ 3 │ +│ 3 │ ᴺᵁᴸᴸ │ +└───┴──────┘ +``` + +پرسوجو `SELECT sum(x), y FROM t_null_big GROUP BY y` نتایج در: + +``` text +┌─sum(x)─┬────y─┐ +│ 4 │ 2 │ +│ 3 │ 3 │ +│ 5 │ ᴺᵁᴸᴸ │ +└────────┴──────┘ +``` + +شما می توانید ببینید که `GROUP BY` برای `y = NULL` خلاصه تا `x`, به عنوان اگر `NULL` این مقدار است. + +اگر شما تصویب چند کلید به `GROUP BY`, نتیجه به شما تمام ترکیبی از انتخاب را, اگر `NULL` یک مقدار خاص بودند. + +#### با اصلاح کننده بالغ {#with-totals-modifier} + +اگر با اصلاح بالغ مشخص شده است, ردیف دیگر محاسبه خواهد شد. این ردیف ستون های کلیدی حاوی مقادیر پیش فرض (صفر یا خطوط خالی) و ستون های توابع جمع شده با مقادیر محاسبه شده در تمام ردیف ها ( “total” ارزش ها). + +این ردیف اضافی خروجی در جانسون است\*, تابسپار\*, و زیبا \* فرمت, به طور جداگانه از ردیف های دیگر. در فرمت های دیگر, این ردیف خروجی نیست. + +در جانسون \* فرمت های, این ردیف خروجی به عنوان یک جداگانه است ‘totals’ رشته. در جدولپار\* فرمت های, ردیف پس از نتیجه اصلی, قبل از یک ردیف خالی (پس از داده های دیگر). در زیبا \* فرمت های ردیف خروجی به عنوان یک جدول جداگانه پس از نتیجه اصلی است. + +`WITH TOTALS` می توان در راه های مختلف اجرا زمانی که داشتن حاضر است. رفتار بستگی به ‘totals\_mode’ تنظیمات. +به طور پیش فرض, `totals_mode = 'before_having'`. در این مورد, ‘totals’ محاسبه شده است در تمام ردیف از جمله کسانی که عبور نمی کند از طریق داشتن و ‘max\_rows\_to\_group\_by’. + +جایگزین های دیگر شامل تنها ردیف است که از طریق داشتن در عبور ‘totals’ و رفتار متفاوت با تنظیم `max_rows_to_group_by` و `group_by_overflow_mode = 'any'`. + +`after_having_exclusive` – Don't include rows that didn't pass through `max_rows_to_group_by`. به عبارت دیگر, ‘totals’ کمتر از و یا به همان تعداد از ردیف به عنوان اگر داشته باشد `max_rows_to_group_by` حذف شد. + +`after_having_inclusive` – Include all the rows that didn't pass through ‘max\_rows\_to\_group\_by’ داخل ‘totals’. به عبارت دیگر, ‘totals’ بیش از و یا به همان تعداد از ردیف به عنوان اگر داشته باشد `max_rows_to_group_by` حذف شد. + +`after_having_auto` – Count the number of rows that passed through HAVING. If it is more than a certain amount (by default, 50%), include all the rows that didn't pass through ‘max\_rows\_to\_group\_by’ داخل ‘totals’. در غیر این صورت, را شامل نمی شود. + +`totals_auto_threshold` – By default, 0.5. The coefficient for `after_having_auto`. + +اگر `max_rows_to_group_by` و `group_by_overflow_mode = 'any'` استفاده نمی شود, تمام تغییرات از `after_having` یکسان هستند و شما می توانید از هر یک از این موارد استفاده کنید, `after_having_auto`). + +شما می توانید با استفاده از مجموع در subqueries از جمله subqueries در پیوستن به بند (در این مورد مربوطه مجموع ارزش ترکیب می شوند). + +#### گروه در حافظه خارجی {#select-group-by-in-external-memory} + +شما می توانید اطلاعات موقت تخلیه به دیسک را قادر به محدود کردن استفاده از حافظه در طول `GROUP BY`. +این [ا\_فزون\_بر\_گونهی\_گونهی زیر\_گروهها](../../operations/settings/settings.md#settings-max_bytes_before_external_group_by) تنظیم تعیین کننده مصرف رم را برای تخلیه می کند `GROUP BY` اطلاعات موقت به سیستم فایل. اگر به 0 (به طور پیش فرض), غیر فعال است. + +هنگام استفاده از `max_bytes_before_external_group_by`, توصیه می کنیم که به شما در تنظیم `max_memory_usage` در مورد دو برابر بالا. این لازم است زیرا دو مرحله برای تجمع وجود دارد: خواندن تاریخ و تشکیل داده های متوسط (1) و ادغام داده های متوسط (2). واژگون اطلاعات به سیستم فایل تنها می تواند در طول مرحله رخ می دهد 1. اگر داده های موقت ریخته نمی شد, سپس مرحله 2 ممکن است نیاز به همان مقدار از حافظه در مرحله 1. + +برای مثال اگر [\_کاساژ بیشینه](../../operations/settings/settings.md#settings_max_memory_usage) به 1000000000 تنظیم شد و شما می خواهید به استفاده از تجمع خارجی, این را حس می کند به مجموعه `max_bytes_before_external_group_by` به 10000000000 و حداکثر\_موری\_اساژ به 20000000000. هنگامی که تجمع خارجی باعث شده است (اگر حداقل یک روگرفت از داده های موقت وجود دارد), حداکثر مصرف رم تنها کمی بیشتر از `max_bytes_before_external_group_by`. + +با پردازش پرس و جو توزیع, تجمع خارجی بر روی سرور از راه دور انجام. به منظور سرور درخواست به استفاده از تنها مقدار کمی از رم, تنظیم `distributed_aggregation_memory_efficient` به 1. + +هنگامی که ادغام داده ها به دیسک سرخ, و همچنین زمانی که ادغام نتایج حاصل از سرور از راه دور زمانی که `distributed_aggregation_memory_efficient` تنظیم فعال است, مصرف تا `1/256 * the_number_of_threads` از مقدار کل رم. + +هنگامی که تجمع خارجی فعال است, اگر کمتر از وجود دارد `max_bytes_before_external_group_by` of data (i.e. data was not flushed), the query runs just as fast as without external aggregation. If any temporary data was flushed, the run time will be several times longer (approximately three times). + +اگر شما یک `ORDER BY` با یک `LIMIT` پس از `GROUP BY`, سپس مقدار رم استفاده می شود بستگی به مقدار داده ها در `LIMIT` نه تو کل میز اما اگر `ORDER BY` ندارد `LIMIT` فراموش نکنید که مرتب سازی خارجی را فعال کنید (`max_bytes_before_external_sort`). + +### محدود کردن بند {#limit-by-clause} + +پرس و جو با `LIMIT n BY expressions` بند اول را انتخاب می کند `n` ردیف برای هر مقدار مجزا از `expressions`. کلید برای `LIMIT BY` می تواند شامل هر تعداد از [عبارتها](../syntax.md#syntax-expressions). + +تاتر از نحو زیر پشتیبانی می کند: + +- `LIMIT [offset_value, ]n BY expressions` +- `LIMIT n OFFSET offset_value BY expressions` + +در طول پردازش پرس و جو, خانه را انتخاب داده دستور داد با مرتب سازی کلید. کلید مرتب سازی به صراحت با استفاده از یک مجموعه [ORDER BY](#select-order-by) بند یا به طور ضمنی به عنوان یک ویژگی از موتور جدول. سپس کلیک کنیداوس اعمال می شود `LIMIT n BY expressions` و اولین را برمی گرداند `n` ردیف برای هر ترکیب مجزا از `expressions`. اگر `OFFSET` مشخص شده است, سپس برای هر بلوک داده که متعلق به یک ترکیب متمایز از `expressions`. `offset_value` تعداد ردیف از ابتدای بلوک و حداکثر می گرداند `n` ردیف به عنوان یک نتیجه. اگر `offset_value` بزرگتر از تعدادی از ردیف در بلوک داده است, کلیک بازگشت صفر ردیف از بلوک. + +`LIMIT BY` مربوط به `LIMIT`. هر دو را می توان در همان پرس و جو استفاده کرد. + +**مثالها** + +جدول نمونه: + +``` sql +CREATE TABLE limit_by(id Int, val Int) ENGINE = Memory; +INSERT INTO limit_by values(1, 10), (1, 11), (1, 12), (2, 20), (2, 21); +``` + +نمایش داده شد: + +``` sql +SELECT * FROM limit_by ORDER BY id, val LIMIT 2 BY id +``` + +``` text +┌─id─┬─val─┐ +│ 1 │ 10 │ +│ 1 │ 11 │ +│ 2 │ 20 │ +│ 2 │ 21 │ +└────┴─────┘ +``` + +``` sql +SELECT * FROM limit_by ORDER BY id, val LIMIT 1, 2 BY id +``` + +``` text +┌─id─┬─val─┐ +│ 1 │ 11 │ +│ 1 │ 12 │ +│ 2 │ 21 │ +└────┴─────┘ +``` + +این `SELECT * FROM limit_by ORDER BY id, val LIMIT 2 OFFSET 1 BY id` پرس و جو همان نتیجه را برمی گرداند. + +پرس و جو زیر را برمی گرداند بالا 5 ارجاع برای هر `domain, device_type` جفت با حداکثر 100 ردیف در مجموع (`LIMIT n BY + LIMIT`). + +``` sql +SELECT + domainWithoutWWW(URL) AS domain, + domainWithoutWWW(REFERRER_URL) AS referrer, + device_type, + count() cnt +FROM hits +GROUP BY domain, referrer, device_type +ORDER BY cnt DESC +LIMIT 5 BY domain, device_type +LIMIT 100 +``` + +### داشتن بند {#having-clause} + +اجازه می دهد تا فیلتر نتیجه پس از گروه های دریافت, شبیه به بند جایی که. +در کجا و در جایی که قبل از تجمع انجام متفاوت است (گروه های), در حالی که پس از انجام. +اگر تجمع انجام نشده است, داشتن نمی توان استفاده کرد. + +### ORDER BY {#select-order-by} + +سفارش توسط بند شامل یک لیست از عبارات, که می تواند هر یک اختصاص داده شود مجموعه خارج از محدوده و یا صعودی (جهت مرتب سازی). اگر جهت مشخص نشده است, صعودی فرض بر این است. صعودی و نزولی در نزولی مرتب شده اند. جهت مرتب سازی شامل یک عبارت واحد, نه به کل لیست. مثال: `ORDER BY Visits DESC, SearchPhrase` + +برای مرتب سازی بر اساس مقادیر رشته, شما می توانید میترا مشخص (مقایسه). مثال: `ORDER BY SearchPhrase COLLATE 'tr'` - برای مرتب سازی بر اساس کلمه کلیدی به ترتیب صعودی, با استفاده از الفبای ترکی, حساس به حروف, فرض کنید که رشته ها سخن گفتن-8 کد گذاری. تلفیق می تواند مشخص شود یا نه برای هر عبارت به منظور به طور مستقل. اگر مرکز کنترل و یا مرکز کنترل خارج رحمی مشخص شده است, تلفیقی بعد از مشخص. هنگام استفاده از برخورد, مرتب سازی است که همیشه غیر حساس به حروف. + +ما فقط توصیه می کنیم با استفاده از تلفیق برای مرتب سازی نهایی تعداد کمی از ردیف, از مرتب سازی با تلفیقی کمتر موثر تر از مرتب سازی طبیعی با بایت است. + +ردیف هایی که دارای مقادیر یکسان برای لیست عبارات مرتب سازی هستند خروجی در جهت دلخواه هستند که همچنین می توانند نامعین (هر بار متفاوت) باشند. +اگر ORDER BY حذف شده منظور از ردیف نیز تعریف نشده و ممکن است nondeterministic به عنوان به خوبی. + +`NaN` و `NULL` مرتب سازی سفارش: + +- با اصلاح کننده `NULLS FIRST` — First `NULL` پس `NaN`, سپس ارزش های دیگر. +- با اصلاح کننده `NULLS LAST` — First the values, then `NaN` پس `NULL`. +- Default — The same as with the `NULLS LAST` تغییردهنده. + +مثال: + +برای جدول + +``` text +┌─x─┬────y─┐ +│ 1 │ ᴺᵁᴸᴸ │ +│ 2 │ 2 │ +│ 1 │ nan │ +│ 2 │ 2 │ +│ 3 │ 4 │ +│ 5 │ 6 │ +│ 6 │ nan │ +│ 7 │ ᴺᵁᴸᴸ │ +│ 6 │ 7 │ +│ 8 │ 9 │ +└───┴──────┘ +``` + +اجرای پرس و جو `SELECT * FROM t_null_nan ORDER BY y NULLS FIRST` برای دریافت: + +``` text +┌─x─┬────y─┐ +│ 1 │ ᴺᵁᴸᴸ │ +│ 7 │ ᴺᵁᴸᴸ │ +│ 1 │ nan │ +│ 6 │ nan │ +│ 2 │ 2 │ +│ 2 │ 2 │ +│ 3 │ 4 │ +│ 5 │ 6 │ +│ 6 │ 7 │ +│ 8 │ 9 │ +└───┴──────┘ +``` + +هنگامی که اعداد ممیز شناور طبقه بندی شده اند, نان جدا از ارزش های دیگر هستند. صرف نظر از نظم مرتب سازی, نان در پایان. به عبارت دیگر برای مرتب سازی صعودی قرار می گیرند همانطور که بزرگتر از همه شماره های دیگر هستند در حالی که برای مرتب سازی کوچکتر از بقیه قرار می گیرند. + +رم کمتر استفاده می شود اگر یک محدودیت به اندازه کافی کوچک است علاوه بر سفارش های مشخص. در غیر این صورت, مقدار حافظه صرف متناسب با حجم داده ها برای مرتب سازی است. برای پردازش پرس و جو توزیع, اگر گروه حذف شده است, مرتب سازی تا حدی بر روی سرور از راه دور انجام, و نتایج در سرور درخواست با هم ادغام شدند. این به این معنی است که برای مرتب سازی توزیع, حجم داده ها برای مرتب کردن می تواند بیشتر از مقدار حافظه بر روی یک سرور واحد. + +در صورتی که رم به اندازه کافی وجود ندارد, ممکن است به انجام مرتب سازی در حافظه خارجی (ایجاد فایل های موقت بر روی یک دیسک). از تنظیمات استفاده کنید `max_bytes_before_external_sort` برای این منظور. اگر قرار است 0 (به طور پیش فرض), مرتب سازی خارجی غیر فعال است. اگر فعال باشد, زمانی که حجم داده ها برای مرتب کردن بر اساس تعداد مشخصی از بایت می رسد, اطلاعات جمع شده مرتب شده و ریخته را به یک فایل موقت. پس از همه داده ها خوانده شده است, تمام فایل های طبقه بندی شده اند با هم ادغام شدند و نتایج خروجی. فایل ها به نوشته /ور/معاونت/تاتر/تی ام پی/ دایرکتوری در پیکربندی (به طور پیش فرض, اما شما می توانید با استفاده از ‘tmp\_path’ پارامتر برای تغییر این تنظیم). + +در حال اجرا یک پرس و جو ممکن است حافظه بیش از استفاده ‘max\_bytes\_before\_external\_sort’. به همین دلیل این تنظیم باید یک مقدار قابل توجهی کوچکتر از ‘max\_memory\_usage’. به عنوان مثال, اگر سرور شما 128 گیگابایت رم و شما نیاز به اجرای یک پرس و جو واحد, تنظیم ‘max\_memory\_usage’ به 100 گیگابایت, و ‘max\_bytes\_before\_external\_sort’ به 80 گیگابایت. + +مرتب سازی خارجی کار می کند بسیار کمتر به طور موثر از مرتب سازی در رم. + +### انتخاب بند {#select-select} + +[عبارتها](../syntax.md#syntax-expressions) مشخص شده در `SELECT` بند بعد از تمام عملیات در بند بالا توضیح محاسبه به پایان رسید. این عبارات کار می کنند به عنوان اگر به ردیف جداگانه در نتیجه اعمال می شود. اگر عبارات در `SELECT` بند شامل مجموع توابع سپس ClickHouse فرآیندهای کل توابع و عبارات استفاده می شود به عنوان استدلال های خود را در طول [GROUP BY](#select-group-by-clause) تجمع. + +اگر شما می خواهید که شامل تمام ستون ها در نتیجه, استفاده از ستاره (`*`) نماد. به عنوان مثال, `SELECT * FROM ...`. + +برای مطابقت با برخی از ستون ها در نتیجه با یک [شماره 2](https://en.wikipedia.org/wiki/RE2_(software)) عبارت منظم می توانید از `COLUMNS` اصطلاح. + +``` sql +COLUMNS('regexp') +``` + +برای مثال جدول را در نظر بگیرید: + +``` sql +CREATE TABLE default.col_names (aa Int8, ab Int8, bc Int8) ENGINE = TinyLog +``` + +پرس و جو زیر داده ها را از تمام ستون های حاوی `a` نماد به نام خود. + +``` sql +SELECT COLUMNS('a') FROM col_names +``` + +``` text +┌─aa─┬─ab─┐ +│ 1 │ 1 │ +└────┴────┘ +``` + +ستون های انتخاب شده به ترتیب حروف الفبا بازگردانده نمی شوند. + +شما می توانید چند استفاده کنید `COLUMNS` عبارات در پرس و جو و اعمال توابع را به خود. + +به عنوان مثال: + +``` sql +SELECT COLUMNS('a'), COLUMNS('c'), toTypeName(COLUMNS('c')) FROM col_names +``` + +``` text +┌─aa─┬─ab─┬─bc─┬─toTypeName(bc)─┐ +│ 1 │ 1 │ 1 │ Int8 │ +└────┴────┴────┴────────────────┘ +``` + +هر ستون توسط `COLUMNS` بیان به تابع به عنوان یک استدلال جداگانه منتقل می شود. همچنین شما می توانید استدلال های دیگر به تابع منتقل می کند اگر از. مراقب باشید در هنگام استفاده از توابع. اگر یک تابع تعداد استدلال شما را به تصویب را پشتیبانی نمی کند, خانه عروسکی می اندازد یک استثنا. + +به عنوان مثال: + +``` sql +SELECT COLUMNS('a') + COLUMNS('c') FROM col_names +``` + +``` text +Received exception from server (version 19.14.1): +Code: 42. DB::Exception: Received from localhost:9000. DB::Exception: Number of arguments for function plus doesn't match: passed 3, should be 2. +``` + +در این مثال, `COLUMNS('a')` بازگرداندن دو ستون: `aa` و `ab`. `COLUMNS('c')` بازگرداندن `bc` ستون. این `+` اپراتور نمی تواند به اعمال 3 استدلال, بنابراین تاتر می اندازد یک استثنا با پیام مربوطه. + +ستون که همسان `COLUMNS` بیان می تواند انواع داده های مختلف داشته باشد. اگر `COLUMNS` هیچ ستون مطابقت ندارد و تنها بیان در است `SELECT`, فاحشه خانه می اندازد یک استثنا. + +### بند مجزا {#select-distinct} + +اگر مشخص شده است, تنها یک ردیف از تمام مجموعه از ردیف به طور کامل تطبیق در نتیجه باقی خواهد ماند. +نتیجه همان خواهد بود که اگر گروه توسط در تمام زمینه های مشخص شده در انتخاب بدون توابع دانه مشخص شد. اما تفاوت های مختلفی از گروه وجود دارد: + +- مجزا را می توان همراه با گروه توسط اعمال می شود. +- هنگامی که سفارش های حذف شده است و حد تعریف شده است, پرس و جو متوقف می شود در حال اجرا بلافاصله پس از تعداد مورد نیاز از ردیف های مختلف خوانده شده است. +- بلوک های داده خروجی به عنوان پردازش می شوند, بدون انتظار برای کل پرس و جو را به پایان برساند در حال اجرا. + +متمایز پشتیبانی نمی شود اگر انتخاب حداقل یک ستون مجموعه ای دارد. + +`DISTINCT` با این نسخهها کار میکند [NULL](../syntax.md) همانطور که اگر `NULL` یک مقدار خاص بودند, و `NULL=NULL`. به عبارت دیگر در `DISTINCT` نتایج, ترکیب های مختلف با `NULL` فقط یک بار رخ می دهد. + +کلیک پشتیبانی با استفاده از `DISTINCT` و `ORDER BY` بند برای ستون های مختلف در یک پرس و جو. این `DISTINCT` بند قبل از اجرا `ORDER BY` بند بند. + +جدول نمونه: + +``` text +┌─a─┬─b─┐ +│ 2 │ 1 │ +│ 1 │ 2 │ +│ 3 │ 3 │ +│ 2 │ 4 │ +└───┴───┘ +``` + +هنگام انتخاب داده ها با `SELECT DISTINCT a FROM t1 ORDER BY b ASC` پرس و جو, ما نتیجه زیر را دریافت کنید: + +``` text +┌─a─┐ +│ 2 │ +│ 1 │ +│ 3 │ +└───┘ +``` + +اگر ما جهت مرتب سازی را تغییر دهیم `SELECT DISTINCT a FROM t1 ORDER BY b DESC` ما نتیجه زیر را دریافت می کنیم: + +``` text +┌─a─┐ +│ 3 │ +│ 1 │ +│ 2 │ +└───┘ +``` + +سطر `2, 4` قبل از مرتب سازی قطع شد. + +نگاهی به این ویژگی پیاده سازی به حساب زمانی که برنامه نویسی نمایش داده شد. + +### بند محدود {#limit-clause} + +`LIMIT m` اجازه می دهد تا شما را به انتخاب اولین `m` ردیف از نتیجه. + +`LIMIT n, m` اجازه می دهد تا شما را به انتخاب اولین `m` ردیف از نتیجه پس از پرش برای اولین بار `n` ردیف این `LIMIT m OFFSET n` نحو نیز پشتیبانی می کند. + +`n` و `m` باید اعداد صحیح غیر منفی باشد. + +اگر وجود ندارد `ORDER BY` بند که به صراحت انواع نتایج, نتیجه ممکن است خودسرانه و نامعین. + +### اتحادیه همه بند {#union-all-clause} + +شما می توانید اتحادیه همه به ترکیب هر تعداد از نمایش داده شد استفاده کنید. مثال: + +``` sql +SELECT CounterID, 1 AS table, toInt64(count()) AS c + FROM test.hits + GROUP BY CounterID + +UNION ALL + +SELECT CounterID, 2 AS table, sum(Sign) AS c + FROM test.visits + GROUP BY CounterID + HAVING c > 0 +``` + +فقط اتحادیه پشتیبانی می شود. اتحادیه به طور منظم (اتحادیه مجزا) پشتیبانی نمی شود. اگر شما نیاز به اتحادیه مجزا, شما می توانید ارسال انتخاب کنید متمایز از زیرخاکی حاوی اتحادیه همه. + +نمایش داده شد که بخش هایی از اتحادیه همه را می توان به طور همزمان اجرا, و نتایج خود را می توان با هم مخلوط. + +ساختار نتایج (تعداد و نوع ستون) باید برای نمایش داده شد مطابقت داشته باشد. اما نام ستون می تواند متفاوت باشد. در این مورد, نام ستون برای نتیجه نهایی خواهد شد از پرس و جو برای اولین بار گرفته شده. نوع ریخته گری برای اتحادیه انجام می شود. برای مثال اگر دو نمایش داده شد در حال ترکیب باید همین زمینه را با غیر-`Nullable` و `Nullable` انواع از یک نوع سازگار, در نتیجه `UNION ALL` دارای یک `Nullable` نوع درست. + +نمایش داده شد که بخش هایی از اتحادیه همه را نمی توان در داخل پرانتز محصور شده است. سفارش و محدودیت برای نمایش داده شد جداگانه به نتیجه نهایی اعمال می شود. اگر شما نیاز به اعمال یک تبدیل به نتیجه نهایی, شما می توانید تمام نمایش داده شد با اتحادیه همه در یک خرده فروشی در بند از قرار. + +### به OUTFILE بند {#into-outfile-clause} + +افزودن `INTO OUTFILE filename` بند (جایی که نام فایل یک رشته تحت اللفظی است) برای تغییر مسیر خروجی پرس و جو به فایل مشخص شده است. +در مقابل خروجی زیر, فایل در سمت سرویس گیرنده ایجاد. پرس و جو شکست مواجه خواهد شد اگر یک فایل با نام فایل مشابه در حال حاضر وجود دارد. +این قابلیت در خط فرمان مشتری و فاحشه خانه در دسترس است-محلی (پرس و جو ارسال شده از طریق رابط اچ.تی. پی شکست خواهد خورد). + +فرمت خروجی به طور پیش فرض جدول است (همان است که در خط فرمان حالت دسته ای مشتری). + +### بند فرمت {#format-clause} + +مشخص ‘FORMAT format’ برای دریافت اطلاعات در هر فرمت مشخص شده است. +شما می توانید این کار را برای راحتی و یا برای ایجاد افسردگی استفاده کنید. +برای کسب اطلاعات بیشتر به بخش مراجعه کنید “Formats”. +اگر بند فرمت حذف شده است, فرمت پیش فرض استفاده شده است, که بستگی به هر دو تنظیمات و رابط مورد استفاده برای دسترسی به دسی بل. برای رابط اچ تی پی و مشتری خط فرمان در حالت دسته ای, فرمت پیش فرض جدولبندی شده است. برای مشتری خط فرمان در حالت تعاملی فرمت پیش فرض است که پیش سازه (این جداول جذاب و جمع و جور). + +هنگام استفاده از خط فرمان مشتری داده ها به مشتری در فرمت موثر داخلی منتقل می شود. مشتری به طور مستقل تفسیر بند فرمت پرس و جو و فرمت های داده های خود را (در نتیجه تسکین شبکه و سرور از بار). + +### در اپراتورها {#select-in-operators} + +این `IN`, `NOT IN`, `GLOBAL IN` و `GLOBAL NOT IN` اپراتورها به طور جداگانه تحت پوشش, از قابلیت های خود را کاملا غنی است. + +سمت چپ اپراتور یا یک ستون یا یک تاپل است. + +مثالها: + +``` sql +SELECT UserID IN (123, 456) FROM ... +SELECT (CounterID, UserID) IN ((34, 123), (101500, 456)) FROM ... +``` + +اگر سمت چپ یک ستون است که در شاخص است, و در سمت راست مجموعه ای از ثابت است, سیستم با استفاده از شاخص برای پردازش پرس و جو. + +Don't list too many values explicitly (i.e. millions). If a data set is large, put it in a temporary table (for example, see the section “External data for query processing”), سپس با استفاده از یک خرده فروشی. + +سمت راست اپراتور می تواند مجموعه ای از عبارات ثابت, مجموعه ای از تاپل با عبارات ثابت (نشان داده شده در نمونه های بالا), و یا به نام یک جدول پایگاه داده و یا زیرخاکی در داخل پرانتز را انتخاب کنید. + +اگر سمت راست اپراتور نام یک جدول است (مثلا, `UserID IN users`), این معادل به خرده فروشی است `UserID IN (SELECT * FROM users)`. با استفاده از این هنگام کار با داده های خارجی است که همراه با پرس و جو ارسال می شود. مثلا, پرس و جو را می توان همراه با مجموعه ای از شناسه کاربر لود شده به ارسال ‘users’ جدول موقت, که باید فیلتر شود. + +اگر در سمت راست اپراتور یک نام جدول است که موتور مجموعه ای است (مجموعه داده های تهیه شده است که همیشه در رم), مجموعه داده خواهد شد بیش از دوباره برای هر پرس و جو ایجاد نمی. + +زیرخاکری ممکن است بیش از یک ستون برای فیلتر کردن تاپل را مشخص کنید. +مثال: + +``` sql +SELECT (CounterID, UserID) IN (SELECT CounterID, UserID FROM ...) FROM ... +``` + +ستون به سمت چپ و راست اپراتور در باید همان نوع. + +اپراتور در و زیرخاکی ممکن است در هر بخشی از پرس و جو رخ می دهد, از جمله در توابع کل و توابع لامبدا. +مثال: + +``` sql +SELECT + EventDate, + avg(UserID IN + ( + SELECT UserID + FROM test.hits + WHERE EventDate = toDate('2014-03-17') + )) AS ratio +FROM test.hits +GROUP BY EventDate +ORDER BY EventDate ASC +``` + +``` text +┌──EventDate─┬────ratio─┐ +│ 2014-03-17 │ 1 │ +│ 2014-03-18 │ 0.807696 │ +│ 2014-03-19 │ 0.755406 │ +│ 2014-03-20 │ 0.723218 │ +│ 2014-03-21 │ 0.697021 │ +│ 2014-03-22 │ 0.647851 │ +│ 2014-03-23 │ 0.648416 │ +└────────────┴──────────┘ +``` + +برای هر روز پس از مارس 17, تعداد درصد تعداد بازدید از صفحات ساخته شده توسط کاربران که سایت در مارس 17 بازدید. +یک خرده فروشی در بند در همیشه اجرا فقط یک بار بر روی یک سرور. هیچ زیرمجموعه وابسته وجود دارد. + +#### پردازش پوچ {#null-processing-1} + +در طول پردازش درخواست, در اپراتور فرض می شود که در نتیجه یک عملیات با [NULL](../syntax.md) همیشه برابر است با `0`, صرف نظر از اینکه `NULL` است در سمت راست یا چپ اپراتور. `NULL` ارزش ها در هر مجموعه داده شامل نمی شود, به یکدیگر مربوط نیست و نمی توان در مقایسه. + +در اینجا یک مثال با است `t_null` جدول: + +``` text +┌─x─┬────y─┐ +│ 1 │ ᴺᵁᴸᴸ │ +│ 2 │ 3 │ +└───┴──────┘ +``` + +در حال اجرا پرس و جو `SELECT x FROM t_null WHERE y IN (NULL,3)` به شما نتیجه زیر را می دهد: + +``` text +┌─x─┐ +│ 2 │ +└───┘ +``` + +شما می توانید ببینید که ردیف که `y = NULL` از نتایج پرس و جو پرتاب می شود. دلیل این است که تاتر نمی توانید تصمیم بگیرید که چه `NULL` در `(NULL,3)` تنظیم, بازگشت `0` به عنوان نتیجه عملیات و `SELECT` این سطر را از خروجی نهایی حذف می کند. + +``` sql +SELECT y IN (NULL, 3) +FROM t_null +``` + +``` text +┌─in(y, tuple(NULL, 3))─┐ +│ 0 │ +│ 1 │ +└───────────────────────┘ +``` + +#### توزیع Subqueries {#select-distributed-subqueries} + +دو گزینه برای در بازدید کنندگان با کارخانه های فرعی وجود دارد (شبیه به می پیوندد): طبیعی `IN` / `JOIN` و `GLOBAL IN` / `GLOBAL JOIN`. در نحوه اجرا برای پردازش پرس و جو توزیع شده متفاوت است. + +!!! attention "توجه" + به یاد داشته باشید که الگوریتم های زیر توضیح داده شده ممکن است متفاوت بسته به کار [تنظیمات](../../operations/settings/settings.md) `distributed_product_mode` تنظیمات. + +هنگام استفاده از به طور منظم در, پرس و جو به سرور از راه دور ارسال, و هر یک از اجرا می شود کارخانه های فرعی در `IN` یا `JOIN` بند بند. + +هنگام استفاده از `GLOBAL IN` / `GLOBAL JOINs`, اول همه زیرمجموعه ها برای اجرا `GLOBAL IN` / `GLOBAL JOINs` و نتایج در جداول موقت جمع می شوند. سپس جداول موقت به هر سرور از راه دور ارسال, جایی که نمایش داده شد با استفاده از این داده های موقت اجرا. + +برای پرس و جو غیر توزیع, استفاده از به طور منظم `IN` / `JOIN`. + +مراقب باشید در هنگام استفاده از کارخانه های فرعی در `IN` / `JOIN` بند برای پردازش پرس و جو توزیع. + +بیایید نگاهی به برخی از نمونه. فرض کنید که هر سرور در خوشه طبیعی است **\_تمل**. هر سرور همچنین دارای یک **توزیع \_تماس** جدول با **توزیع شده** نوع, که به نظر می رسد در تمام سرور در خوشه. + +برای پرس و جو به **توزیع \_تماس** پرس و جو به تمام سرورهای راه دور ارسال می شود و با استفاده از **\_تمل**. + +برای مثال پرس و جو + +``` sql +SELECT uniq(UserID) FROM distributed_table +``` + +به تمام سرورهای راه دور ارسال می شود + +``` sql +SELECT uniq(UserID) FROM local_table +``` + +و به صورت موازی اجرا می شود تا زمانی که به مرحله ای برسد که نتایج متوسط می تواند ترکیب شود. سپس نتایج میانی به سرور درخواست کننده بازگردانده می شود و با هم ادغام می شوند و نتیجه نهایی به مشتری ارسال می شود. + +حالا اجازه دهید به بررسی یک پرس و جو با در: + +``` sql +SELECT uniq(UserID) FROM distributed_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM local_table WHERE CounterID = 34) +``` + +- محاسبه تقاطع مخاطبان از دو سایت. + +این پرس و جو خواهد شد به تمام سرور از راه دور به عنوان ارسال می شود + +``` sql +SELECT uniq(UserID) FROM local_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM local_table WHERE CounterID = 34) +``` + +به عبارت دیگر, داده های تعیین شده در بند در خواهد شد بر روی هر سرور به طور مستقل جمع, تنها در سراسر داده است که به صورت محلی بر روی هر یک از سرور های ذخیره شده. + +این به درستی و بهینه کار خواهد کرد اگر شما برای این مورد تهیه و داده ها در سراسر سرورهای خوشه گسترش یافته اند به طوری که داده ها را برای یک شناسه تنها ساکن به طور کامل بر روی یک سرور واحد. در این مورد, تمام اطلاعات لازم در دسترس خواهد بود به صورت محلی بر روی هر سرور. در غیر این صورت نتیجه نادرست خواهد بود. ما به این تنوع از پرس و جو به عنوان مراجعه کنید “local IN”. + +برای اصلاح چگونه پرس و جو کار می کند زمانی که داده ها به طور تصادفی در سراسر سرور خوشه گسترش, شما می توانید مشخص **توزیع \_تماس** در داخل یک خرده فروشی. پرس و جو شبیه به این خواهد بود: + +``` sql +SELECT uniq(UserID) FROM distributed_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM distributed_table WHERE CounterID = 34) +``` + +این پرس و جو خواهد شد به تمام سرور از راه دور به عنوان ارسال می شود + +``` sql +SELECT uniq(UserID) FROM local_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM distributed_table WHERE CounterID = 34) +``` + +خرده فروشی شروع خواهد شد در حال اجرا بر روی هر سرور از راه دور. پس از زیرخاکری با استفاده از یک جدول توزیع, خرده فروشی است که در هر سرور از راه دور خواهد شد به هر سرور از راه دور به عنوان خشمگین + +``` sql +SELECT UserID FROM local_table WHERE CounterID = 34 +``` + +مثلا, اگر شما یک خوشه از 100 سرور, اجرای کل پرس و جو نیاز 10,000 درخواست ابتدایی, که به طور کلی در نظر گرفته غیر قابل قبول. + +در چنین مواردی, شما همیشه باید جهانی به جای در استفاده از. بیایید نگاه کنیم که چگونه برای پرس و جو کار می کند + +``` sql +SELECT uniq(UserID) FROM distributed_table WHERE CounterID = 101500 AND UserID GLOBAL IN (SELECT UserID FROM distributed_table WHERE CounterID = 34) +``` + +سرور درخواست کننده خرده فروشی را اجرا خواهد کرد + +``` sql +SELECT UserID FROM distributed_table WHERE CounterID = 34 +``` + +و در نتیجه خواهد شد در یک جدول موقت در رم قرار داده است. سپس درخواست خواهد شد به هر سرور از راه دور به عنوان ارسال + +``` sql +SELECT uniq(UserID) FROM local_table WHERE CounterID = 101500 AND UserID GLOBAL IN _data1 +``` + +و جدول موقت `_data1` خواهد شد به هر سرور از راه دور با پرس و جو ارسال (نام جدول موقت پیاده سازی تعریف شده است). + +این مطلوب تر از استفاده از نرمال در است. با این حال, نگه داشتن نکات زیر را در ذهن: + +1. هنگام ایجاد یک جدول موقت داده های منحصر به فرد ساخته شده است. برای کاهش حجم داده های منتقل شده بر روی شبکه مشخص متمایز در زیرخاکری. (شما لازم نیست برای انجام این کار برای عادی در.) +2. جدول موقت خواهد شد به تمام سرور از راه دور ارسال. انتقال برای توپولوژی شبکه به حساب نمی. مثلا, اگر 10 سرور از راه دور در یک مرکز داده است که در رابطه با سرور درخواست بسیار از راه دور اقامت, داده ها ارسال خواهد شد 10 بار بیش از کانال به مرکز داده از راه دور. سعی کنید برای جلوگیری از مجموعه داده های بزرگ در هنگام استفاده از جهانی در. +3. هنگام انتقال داده ها به سرور از راه دور, محدودیت در پهنای باند شبکه قابل تنظیم نیست. شما ممکن است شبکه بیش از حد. +4. سعی کنید برای توزیع داده ها در سراسر سرور به طوری که شما لازم نیست که به استفاده از جهانی را به صورت منظم. +5. اگر شما نیاز به استفاده از جهانی در اغلب, برنامه ریزی محل خوشه خانه کلیک به طوری که یک گروه واحد از کپی ساکن در بیش از یک مرکز داده با یک شبکه سریع بین, به طوری که یک پرس و جو را می توان به طور کامل در یک مرکز داده واحد پردازش. + +همچنین حس می کند برای مشخص کردن یک جدول محلی در `GLOBAL IN` بند, در صورتی که این جدول محلی تنها بر روی سرور درخواست در دسترس است و شما می خواهید به استفاده از داده ها را از روی سرور از راه دور. + +### ارزش های شدید {#extreme-values} + +علاوه بر نتایج, شما همچنین می توانید حداقل و حداکثر ارزش برای ستون نتایج از. برای انجام این کار, تنظیم **افراط** تنظیم به 1. حداقل و حداکثر برای انواع عددی محاسبه, تاریخ, و تاریخ با بار. برای ستون های دیگر مقادیر پیش فرض خروجی هستند. + +An extra two rows are calculated – the minimums and maximums, respectively. These extra two rows are output in `JSON*`, `TabSeparated*` و `Pretty*` [فرشها](../../interfaces/formats.md), جدا از ردیف های دیگر. خروجی برای فرمت های دیگر نیستند. + +داخل `JSON*` فرمت, ارزش شدید خروجی در یک جداگانه ‘extremes’ رشته. داخل `TabSeparated*` فرمت, ردیف پس از نتیجه اصلی, و بعد از ‘totals’ اگر در حال حاضر. این است که توسط یک ردیف خالی قبل (پس از داده های دیگر). داخل `Pretty*` فرمت, ردیف خروجی به عنوان یک جدول جداگانه پس از نتیجه اصلی است, و بعد از `totals` اگر در حال حاضر. + +مقادیر شدید برای ردیف قبل محاسبه می شود `LIMIT` اما بعد از `LIMIT BY`. با این حال, هنگام استفاده از `LIMIT offset, size`, ردیف قبل از `offset` در `extremes`. در درخواست جریان, نتیجه نیز ممکن است شامل تعداد کمی از ردیف که از طریق تصویب `LIMIT`. + +### یادداشتها {#notes} + +این `GROUP BY` و `ORDER BY` بند انجام استدلال موضعی را پشتیبانی نمی کند. این در تضاد خروجی زیر, اما مطابق با استاندارد گذاشتن. +به عنوان مثال, `GROUP BY 1, 2` will be interpreted as grouping by constants (i.e. aggregation of all rows into one). + +شما می توانید مترادف استفاده کنید (`AS` نام مستعار) در هر بخشی از یک پرس و جو. + +شما می توانید یک ستاره در هر بخشی از یک پرس و جو به جای بیان قرار داده است. هنگامی که پرس و جو تجزیه و تحلیل, ستاره به یک لیست از تمام ستون جدول گسترش (به استثنای `MATERIALIZED` و `ALIAS` ستون). تنها چند مورد وجود دارد که با استفاده از ستاره توجیه می شود: + +- هنگام ایجاد یک روگرفت جدول. +- برای جداول حاوی فقط چند ستون, مانند جداول سیستم. +- برای گرفتن اطلاعات در مورد چه ستون در یک جدول هستند. در این مورد, تنظیم `LIMIT 1`. اما بهتر است از `DESC TABLE` پرس و جو. +- هنگامی که فیلتراسیون قوی در تعداد کمی از ستون ها با استفاده از وجود دارد `PREWHERE`. +- در subqueries (از ستون های که مورد نیاز نیست برای خارجی پرس و جو از مطالعه حذف شدند subqueries). + +در تمام موارد دیگر, ما توصیه نمی با استفاده از ستاره, زیرا تنها به شما می دهد اشکالاتی از یک سندرم روده تحریک پذیر ستونی به جای مزایای. به عبارت دیگر با استفاده از ستاره توصیه نمی شود. + +[مقاله اصلی](https://clickhouse.tech/docs/en/query_language/select/) diff --git a/docs/fr/sql-reference/statements/select.md b/docs/fr/sql-reference/statements/select.md index 659517dd0be..9f39ca9ab0a 100644 --- a/docs/fr/sql-reference/statements/select.md +++ b/docs/fr/sql-reference/statements/select.md @@ -1,11 +1,11 @@ --- machine_translated: true -machine_translated_rev: f865c9653f9df092694258e0ccdd733c339112f5 +machine_translated_rev: 0f7ef7704d018700049223525bad4a63911b6e70 toc_priority: 33 toc_title: SELECT --- -# Sélectionnez La Syntaxe Des requêtes {#select-queries-syntax} +# Sélectionnez la syntaxe des requêtes {#select-queries-syntax} `SELECT` effectue la récupération des données. @@ -28,21 +28,21 @@ SELECT [DISTINCT] expr_list [FORMAT format] ``` -Toutes les clauses sont facultatives, à l’exception de la liste d’expressions requise immédiatement après SELECT. -Les clauses ci-dessous sont décrites dans presque le même ordre que dans l’exécution de la requête convoyeur. +Toutes les clauses sont facultatives, à l'exception de la liste d'expressions requise immédiatement après SELECT. +Les clauses ci-dessous sont décrites dans presque le même ordre que dans l'exécution de la requête convoyeur. Si la requête omet le `DISTINCT`, `GROUP BY` et `ORDER BY` les clauses et les `IN` et `JOIN` sous-requêtes, la requête sera complètement traitée en flux, en utilisant O (1) quantité de RAM. -Sinon, la requête peut consommer beaucoup de RAM si les restrictions appropriées ne sont pas spécifiées: `max_memory_usage`, `max_rows_to_group_by`, `max_rows_to_sort`, `max_rows_in_distinct`, `max_bytes_in_distinct`, `max_rows_in_set`, `max_bytes_in_set`, `max_rows_in_join`, `max_bytes_in_join`, `max_bytes_before_external_sort`, `max_bytes_before_external_group_by`. Pour plus d’informations, consultez la section “Settings”. Il est possible d’utiliser le tri externe (sauvegarde des tables temporaires sur un disque) et l’agrégation externe. `The system does not have "merge join"`. +Sinon, la requête peut consommer beaucoup de RAM si les restrictions appropriées ne sont pas spécifiées: `max_memory_usage`, `max_rows_to_group_by`, `max_rows_to_sort`, `max_rows_in_distinct`, `max_bytes_in_distinct`, `max_rows_in_set`, `max_bytes_in_set`, `max_rows_in_join`, `max_bytes_in_join`, `max_bytes_before_external_sort`, `max_bytes_before_external_group_by`. Pour plus d'informations, consultez la section “Settings”. Il est possible d'utiliser le tri externe (sauvegarde des tables temporaires sur un disque) et l'agrégation externe. `The system does not have "merge join"`. -### AVEC La Clause {#with-clause} +### AVEC la Clause {#with-clause} Cette section prend en charge les Expressions de Table courantes ([CTE](https://en.wikipedia.org/wiki/Hierarchical_and_recursive_queries_in_SQL)), avec quelques limitations: 1. Les requêtes récursives ne sont pas prises en charge -2. Lorsque la sous-requête est utilisée à l’intérieur avec section, son résultat doit être scalaire avec exactement une ligne -3. Les résultats d’Expression ne sont pas disponibles dans les sous requêtes +2. Lorsque la sous-requête est utilisée à l'intérieur avec section, son résultat doit être scalaire avec exactement une ligne +3. Les résultats d'Expression ne sont pas disponibles dans les sous requêtes Les résultats des expressions de clause WITH peuvent être utilisés dans la clause SELECT. -Exemple 1: Utilisation d’une expression constante comme “variable” +Exemple 1: Utilisation d'une expression constante comme “variable” ``` sql WITH '2019-08-01 15:23:00' as ts_upper_bound @@ -53,7 +53,7 @@ WHERE EventTime <= ts_upper_bound ``` -Exemple 2: Expulsion de la somme(octets) résultat de l’expression de clause SELECT de la liste de colonnes +Exemple 2: Expulsion de la somme(octets) résultat de l'expression de clause SELECT de la liste de colonnes ``` sql WITH sum(bytes) as s @@ -84,8 +84,8 @@ ORDER BY table_disk_usage DESC LIMIT 10 ``` -Exemple 4: réutilisation de l’expression dans la sous-requête -Comme solution de contournement pour la limitation actuelle de l’utilisation de l’expression dans les sous-requêtes, Vous pouvez la dupliquer. +Exemple 4: réutilisation de l'expression dans la sous-requête +Comme solution de contournement pour la limitation actuelle de l'utilisation de l'expression dans les sous-requêtes, Vous pouvez la dupliquer. ``` sql WITH ['hello'] AS hello @@ -105,10 +105,10 @@ FROM └───────────┴───────────┘ ``` -### De La Clause {#select-from} +### De la Clause {#select-from} Si la clause FROM est omise, les données seront lues à partir `system.one` table. -Le `system.one` table contient exactement une ligne (cette table remplit le même but que la table double trouvée dans d’autres SGBD). +Le `system.one` table contient exactement une ligne (cette table remplit le même but que la table double trouvée dans d'autres SGBD). Le `FROM` clause spécifie la source à partir de laquelle lire les données: @@ -118,8 +118,8 @@ Le `FROM` clause spécifie la source à partir de laquelle lire les données: `ARRAY JOIN` et le régulier `JOIN` peuvent également être inclus (voir ci-dessous). -Au lieu d’une table, l’ `SELECT` sous-requête peut être spécifiée entre parenthèses. -Contrairement à SQL standard, un synonyme n’a pas besoin d’être spécifié après une sous-requête. +Au lieu d'une table, l' `SELECT` sous-requête peut être spécifiée entre parenthèses. +Contrairement à SQL standard, un synonyme n'a pas besoin d'être spécifié après une sous-requête. Pour exécuter une requête, toutes les colonnes mentionnées dans la requête sont extraites de la table appropriée. Toutes les colonnes non nécessaires pour la requête externe sont rejetées des sous-requêtes. Si une requête ne répertorie aucune colonne (par exemple, `SELECT count() FROM t`), une colonne est extraite de la table de toute façon (la plus petite est préférée), afin de calculer le nombre de lignes. @@ -130,49 +130,49 @@ Applicable lors de la sélection de données à partir de tables [MergeTree](../ Également pris en charge pour: - [Répliqué](../../engines/table-engines/mergetree-family/replication.md) les versions de `MergeTree` moteur. -- [Vue](../../engines/table-engines/special/view.md), [Tampon](../../engines/table-engines/special/buffer.md), [Distribué](../../engines/table-engines/special/distributed.md), et [MaterializedView](../../engines/table-engines/special/materializedview.md) moteurs qui fonctionnent sur d’autres moteurs, à condition qu’ils aient été créés sur `MergeTree`-tables de moteur. +- [Vue](../../engines/table-engines/special/view.md), [Tampon](../../engines/table-engines/special/buffer.md), [Distribué](../../engines/table-engines/special/distributed.md), et [MaterializedView](../../engines/table-engines/special/materializedview.md) moteurs qui fonctionnent sur d'autres moteurs, à condition qu'ils aient été créés sur `MergeTree`-tables de moteur. Requêtes qui utilisent `FINAL` sont exécutés pas aussi vite que les requêtes similaires qui ne le font pas, car: -- La requête est exécutée dans un seul thread et les données sont fusionnées lors de l’exécution de la requête. +- La requête est exécutée dans un seul thread et les données sont fusionnées lors de l'exécution de la requête. - Les requêtes avec `FINAL` lire les colonnes de clé primaire en plus des colonnes spécifiées dans la requête. -Dans la plupart des cas, évitez d’utiliser `FINAL`. +Dans la plupart des cas, évitez d'utiliser `FINAL`. -### Exemple De Clause {#select-sample-clause} +### Exemple de Clause {#select-sample-clause} Le `SAMPLE` la clause permet un traitement de requête approximatif. -Lorsque l’échantillonnage de données est activé, la requête n’est pas effectuée sur toutes les données, mais uniquement sur une certaine fraction de données (échantillon). Par exemple, si vous avez besoin de calculer des statistiques pour toutes les visites, il suffit d’exécuter la requête sur le 1/10 de la fraction de toutes les visites, puis multiplier le résultat par 10. +Lorsque l'échantillonnage de données est activé, la requête n'est pas effectuée sur toutes les données, mais uniquement sur une certaine fraction de données (échantillon). Par exemple, si vous avez besoin de calculer des statistiques pour toutes les visites, il suffit d'exécuter la requête sur le 1/10 de la fraction de toutes les visites, puis multiplier le résultat par 10. Le traitement approximatif des requêtes peut être utile dans les cas suivants: - Lorsque vous avez des exigences de synchronisation strictes (comme \<100ms), mais que vous ne pouvez pas justifier le coût des ressources matérielles supplémentaires pour y répondre. -- Lorsque vos données brutes ne sont pas précises, l’approximation ne dégrade pas sensiblement la qualité. +- Lorsque vos données brutes ne sont pas précises, l'approximation ne dégrade pas sensiblement la qualité. - Les exigences commerciales ciblent des résultats approximatifs (pour la rentabilité, ou afin de commercialiser des résultats exacts aux utilisateurs premium). !!! note "Note" - Vous ne pouvez utiliser l’échantillonnage qu’avec les tables [MergeTree](../../engines/table-engines/mergetree-family/mergetree.md) famille, et seulement si l’expression d’échantillonnage a été spécifiée lors de la création de la table (voir [Moteur MergeTree](../../engines/table-engines/mergetree-family/mergetree.md#table_engine-mergetree-creating-a-table)). + Vous ne pouvez utiliser l'échantillonnage qu'avec les tables [MergeTree](../../engines/table-engines/mergetree-family/mergetree.md) famille, et seulement si l'expression d'échantillonnage a été spécifiée lors de la création de la table (voir [Moteur MergeTree](../../engines/table-engines/mergetree-family/mergetree.md#table_engine-mergetree-creating-a-table)). -Les caractéristiques de l’échantillonnage des données sont énumérées ci-dessous: +Les caractéristiques de l'échantillonnage des données sont énumérées ci-dessous: -- L’échantillonnage de données est un mécanisme déterministe. Le résultat de la même `SELECT .. SAMPLE` la requête est toujours le même. -- L’échantillonnage fonctionne de manière cohérente pour différentes tables. Pour les tables avec une seule clé d’échantillonnage, un échantillon avec le même coefficient sélectionne toujours le même sous-ensemble de données possibles. Par exemple, un exemple d’ID utilisateur prend des lignes avec le même sous-ensemble de tous les ID utilisateur possibles de différentes tables. Cela signifie que vous pouvez utiliser l’exemple dans les sous-requêtes dans la [IN](#select-in-operators) clause. En outre, vous pouvez joindre des échantillons en utilisant le [JOIN](#select-join) clause. -- L’échantillonnage permet de lire moins de données à partir d’un disque. Notez que vous devez spécifier l’échantillonnage clé correctement. Pour plus d’informations, voir [Création d’une Table MergeTree](../../engines/table-engines/mergetree-family/mergetree.md#table_engine-mergetree-creating-a-table). +- L'échantillonnage de données est un mécanisme déterministe. Le résultat de la même `SELECT .. SAMPLE` la requête est toujours le même. +- L'échantillonnage fonctionne de manière cohérente pour différentes tables. Pour les tables avec une seule clé d'échantillonnage, un échantillon avec le même coefficient sélectionne toujours le même sous-ensemble de données possibles. Par exemple, un exemple d'ID utilisateur prend des lignes avec le même sous-ensemble de tous les ID utilisateur possibles de différentes tables. Cela signifie que vous pouvez utiliser l'exemple dans les sous-requêtes dans la [IN](#select-in-operators) clause. En outre, vous pouvez joindre des échantillons en utilisant le [JOIN](#select-join) clause. +- L'échantillonnage permet de lire moins de données à partir d'un disque. Notez que vous devez spécifier l'échantillonnage clé correctement. Pour plus d'informations, voir [Création d'une Table MergeTree](../../engines/table-engines/mergetree-family/mergetree.md#table_engine-mergetree-creating-a-table). -Pour l’ `SAMPLE` clause la syntaxe suivante est prise en charge: +Pour l' `SAMPLE` clause la syntaxe suivante est prise en charge: | SAMPLE Clause Syntax | Description | |----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `SAMPLE k` | Ici `k` est le nombre de 0 à 1.
La requête est exécutée sur `k` fraction des données. Exemple, `SAMPLE 0.1` exécute la requête sur 10% des données. [Lire plus](#select-sample-k) | -| `SAMPLE n` | Ici `n` est un entier suffisamment grand.
La requête est exécutée sur un échantillon d’au moins `n` lignes (mais pas significativement plus que cela). Exemple, `SAMPLE 10000000` exécute la requête sur un minimum de 10 000 000 lignes. [Lire plus](#select-sample-n) | -| `SAMPLE k OFFSET m` | Ici `k` et `m` sont les nombres de 0 à 1.
La requête est exécutée sur un échantillon de `k` fraction des données. Les données utilisées pour l’échantillon est compensée par `m` fraction. [Lire plus](#select-sample-offset) | +| `SAMPLE n` | Ici `n` est un entier suffisamment grand.
La requête est exécutée sur un échantillon d'au moins `n` lignes (mais pas significativement plus que cela). Exemple, `SAMPLE 10000000` exécute la requête sur un minimum de 10 000 000 lignes. [Lire plus](#select-sample-n) | +| `SAMPLE k OFFSET m` | Ici `k` et `m` sont les nombres de 0 à 1.
La requête est exécutée sur un échantillon de `k` fraction des données. Les données utilisées pour l'échantillon est compensée par `m` fraction. [Lire plus](#select-sample-offset) | #### SAMPLE K {#select-sample-k} Ici `k` est le nombre de 0 à 1 (les notations fractionnaires et décimales sont prises en charge). Exemple, `SAMPLE 1/2` ou `SAMPLE 0.5`. -Dans un `SAMPLE k` clause, l’échantillon est prélevé à partir de la `k` fraction des données. L’exemple est illustré ci-dessous: +Dans un `SAMPLE k` clause, l'échantillon est prélevé à partir de la `k` fraction des données. L'exemple est illustré ci-dessous: ``` sql SELECT @@ -186,19 +186,19 @@ GROUP BY Title ORDER BY PageViews DESC LIMIT 1000 ``` -Dans cet exemple, la requête est exécutée sur un échantillon de 0,1 (10%) de données. Les valeurs des fonctions d’agrégat ne sont pas corrigées automatiquement, donc pour obtenir un résultat approximatif, la valeur `count()` est multiplié manuellement par 10. +Dans cet exemple, la requête est exécutée sur un échantillon de 0,1 (10%) de données. Les valeurs des fonctions d'agrégat ne sont pas corrigées automatiquement, donc pour obtenir un résultat approximatif, la valeur `count()` est multiplié manuellement par 10. #### SAMPLE N {#select-sample-n} Ici `n` est un entier suffisamment grand. Exemple, `SAMPLE 10000000`. -Dans ce cas, la requête est exécutée sur un échantillon d’au moins `n` lignes (mais pas significativement plus que cela). Exemple, `SAMPLE 10000000` exécute la requête sur un minimum de 10 000 000 lignes. +Dans ce cas, la requête est exécutée sur un échantillon d'au moins `n` lignes (mais pas significativement plus que cela). Exemple, `SAMPLE 10000000` exécute la requête sur un minimum de 10 000 000 lignes. -Puisque l’unité minimale pour la lecture des données est un granule (sa taille est définie par le `index_granularity` de réglage), il est logique de définir un échantillon beaucoup plus grand que la taille du granule. +Puisque l'unité minimale pour la lecture des données est un granule (sa taille est définie par le `index_granularity` de réglage), il est logique de définir un échantillon beaucoup plus grand que la taille du granule. -Lors de l’utilisation de la `SAMPLE n` clause, vous ne savez pas quel pourcentage relatif de données a été traité. Donc, vous ne connaissez pas le coefficient par lequel les fonctions agrégées doivent être multipliées. L’utilisation de la `_sample_factor` colonne virtuelle pour obtenir le résultat approximatif. +Lors de l'utilisation de la `SAMPLE n` clause, vous ne savez pas quel pourcentage relatif de données a été traité. Donc, vous ne connaissez pas le coefficient par lequel les fonctions agrégées doivent être multipliées. L'utilisation de la `_sample_factor` colonne virtuelle pour obtenir le résultat approximatif. -Le `_sample_factor` colonne contient des coefficients relatifs qui sont calculés dynamiquement. Cette colonne est créée automatiquement lorsque vous [créer](../../engines/table-engines/mergetree-family/mergetree.md#table_engine-mergetree-creating-a-table) une table avec la clé d’échantillonnage spécifiée. Les exemples d’utilisation de la `_sample_factor` colonne sont indiqués ci-dessous. +Le `_sample_factor` colonne contient des coefficients relatifs qui sont calculés dynamiquement. Cette colonne est créée automatiquement lorsque vous [créer](../../engines/table-engines/mergetree-family/mergetree.md#table_engine-mergetree-creating-a-table) une table avec la clé d'échantillonnage spécifiée. Les exemples d'utilisation de la `_sample_factor` colonne sont indiqués ci-dessous. Considérons la table `visits` qui contient des statistiques sur les visites de site. Le premier exemple montre comment calculer le nombre de pages vues: @@ -208,7 +208,7 @@ FROM visits SAMPLE 10000000 ``` -L’exemple suivant montre comment calculer le nombre total de visites: +L'exemple suivant montre comment calculer le nombre total de visites: ``` sql SELECT sum(_sample_factor) @@ -216,7 +216,7 @@ FROM visits SAMPLE 10000000 ``` -L’exemple ci-dessous montre comment calculer la durée moyenne de la session. Notez que vous n’avez pas besoin d’utiliser le coefficient relatif pour calculer les valeurs moyennes. +L'exemple ci-dessous montre comment calculer la durée moyenne de la session. Notez que vous n'avez pas besoin d'utiliser le coefficient relatif pour calculer les valeurs moyennes. ``` sql SELECT avg(Duration) @@ -234,7 +234,7 @@ Ici `k` et `m` sont des nombres de 0 à 1. Des exemples sont présentés ci-dess SAMPLE 1/10 ``` -Dans cet exemple, l’échantillon représente 1 / 10e de toutes les données: +Dans cet exemple, l'échantillon représente 1 / 10e de toutes les données: `[++------------]` @@ -248,9 +248,9 @@ Ici, un échantillon de 10% est prélevé à partir de la seconde moitié des do `[------++------]` -### Clause De Jointure De Tableau {#select-array-join-clause} +### Clause de jointure de tableau {#select-array-join-clause} -Permet l’exécution de `JOIN` avec un tableau ou une structure de données imbriquée. L’intention est similaire à la [arrayJoin](../../sql-reference/functions/array-join.md#functions_arrayjoin) la fonction, mais sa fonctionnalité est plus large. +Permet l'exécution de `JOIN` avec un tableau ou une structure de données imbriquée. L'intention est similaire à la [arrayJoin](../functions/array-join.md#functions_arrayjoin) la fonction, mais sa fonctionnalité est plus large. ``` sql SELECT @@ -260,16 +260,16 @@ FROM ... ``` -Vous pouvez spécifier qu’un seul `ARRAY JOIN` la clause dans une requête. +Vous pouvez spécifier qu'un seul `ARRAY JOIN` la clause dans une requête. -L’ordre d’exécution de la requête est optimisé lors de l’exécution `ARRAY JOIN`. Bien `ARRAY JOIN` doit toujours être spécifié avant l’ `WHERE/PREWHERE` clause, il peut être effectué soit avant `WHERE/PREWHERE` (si le résultat est nécessaire dans cette clause), ou après l’avoir terminé (pour réduire le volume de calculs). L’ordre de traitement est contrôlée par l’optimiseur de requête. +L'ordre d'exécution de la requête est optimisé lors de l'exécution `ARRAY JOIN`. Bien `ARRAY JOIN` doit toujours être spécifié avant l' `WHERE/PREWHERE` clause, il peut être effectué soit avant `WHERE/PREWHERE` (si le résultat est nécessaire dans cette clause), ou après l'avoir terminé (pour réduire le volume de calculs). L'ordre de traitement est contrôlée par l'optimiseur de requête. Types pris en charge de `ARRAY JOIN` sont énumérés ci-dessous: - `ARRAY JOIN` - Dans ce cas, des tableaux vides ne sont pas inclus dans le résultat de `JOIN`. -- `LEFT ARRAY JOIN` - Le résultat de `JOIN` contient des lignes avec des tableaux vides. La valeur d’un tableau vide est définie sur la valeur par défaut pour le type d’élément de tableau (généralement 0, chaîne vide ou NULL). +- `LEFT ARRAY JOIN` - Le résultat de `JOIN` contient des lignes avec des tableaux vides. La valeur d'un tableau vide est définie sur la valeur par défaut pour le type d'élément de tableau (généralement 0, chaîne vide ou NULL). -Les exemples ci-dessous illustrent l’utilisation de la `ARRAY JOIN` et `LEFT ARRAY JOIN` clause. Créons une table avec un [Tableau](../../sql-reference/data-types/array.md) tapez colonne et insérez des valeurs dedans: +Les exemples ci-dessous illustrent l'utilisation de la `ARRAY JOIN` et `LEFT ARRAY JOIN` clause. Créons une table avec un [Tableau](../../sql-reference/data-types/array.md) tapez colonne et insérez des valeurs dedans: ``` sql CREATE TABLE arrays_test @@ -290,7 +290,7 @@ VALUES ('Hello', [1,2]), ('World', [3,4,5]), ('Goodbye', []); └─────────────┴─────────┘ ``` -L’exemple ci-dessous utilise la `ARRAY JOIN` clause: +L'exemple ci-dessous utilise la `ARRAY JOIN` clause: ``` sql SELECT s, arr @@ -308,7 +308,7 @@ ARRAY JOIN arr; └───────┴─────┘ ``` -L’exemple suivant utilise l’ `LEFT ARRAY JOIN` clause: +L'exemple suivant utilise l' `LEFT ARRAY JOIN` clause: ``` sql SELECT s, arr @@ -327,9 +327,9 @@ LEFT ARRAY JOIN arr; └─────────────┴─────┘ ``` -#### À L’Aide D’Alias {#using-aliases} +#### À L'Aide D'Alias {#using-aliases} -Un alias peut être spécifié pour un tableau `ARRAY JOIN` clause. Dans ce cas, un élément de tableau peut être consulté par ce pseudonyme, mais le tableau lui-même est accessible par le nom d’origine. Exemple: +Un alias peut être spécifié pour un tableau `ARRAY JOIN` clause. Dans ce cas, un élément de tableau peut être consulté par ce pseudonyme, mais le tableau lui-même est accessible par le nom d'origine. Exemple: ``` sql SELECT s, arr, a @@ -387,7 +387,7 @@ ARRAY JOIN arr AS a, arrayEnumerate(arr) AS num, arrayMap(x -> x + 1, arr) AS ma └───────┴─────────┴───┴─────┴────────┘ ``` -L’exemple ci-dessous utilise la [arrayEnumerate](../../sql-reference/functions/array-functions.md#array_functions-arrayenumerate) fonction: +L'exemple ci-dessous utilise la [arrayEnumerate](../../sql-reference/functions/array-functions.md#array_functions-arrayenumerate) fonction: ``` sql SELECT s, arr, a, num, arrayEnumerate(arr) @@ -405,7 +405,7 @@ ARRAY JOIN arr AS a, arrayEnumerate(arr) AS num; └───────┴─────────┴───┴─────┴─────────────────────┘ ``` -#### Jointure De Tableau Avec La Structure De données imbriquée {#array-join-with-nested-data-structure} +#### Jointure de tableau avec la Structure de données imbriquée {#array-join-with-nested-data-structure} `ARRAY`Rejoindre " fonctionne également avec [structures de données imbriquées](../../sql-reference/data-types/nested-data-structures/nested.md). Exemple: @@ -500,7 +500,7 @@ ARRAY JOIN nest AS n; └───────┴─────┴─────┴─────────┴────────────┘ ``` -Exemple d’utilisation de l’ [arrayEnumerate](../../sql-reference/functions/array-functions.md#array_functions-arrayenumerate) fonction: +Exemple d'utilisation de l' [arrayEnumerate](../../sql-reference/functions/array-functions.md#array_functions-arrayenumerate) fonction: ``` sql SELECT s, `n.x`, `n.y`, `nest.x`, `nest.y`, num @@ -518,7 +518,7 @@ ARRAY JOIN nest AS n, arrayEnumerate(`nest.x`) AS num; └───────┴─────┴─────┴─────────┴────────────┴─────┘ ``` -### Clause De JOINTURE {#select-join} +### Clause de JOINTURE {#select-join} Rejoint les données dans la normale [SQL JOIN](https://en.wikipedia.org/wiki/Join_(SQL)) sens. @@ -534,7 +534,7 @@ FROM Les noms de table peuvent être spécifiés au lieu de `` et ``. Ceci est équivalent à la `SELECT * FROM table` sous-requête, sauf dans un cas particulier lorsque la table a [Rejoindre](../../engines/table-engines/special/join.md) engine – an array prepared for joining. -#### Types Pris En Charge De `JOIN` {#select-join-types} +#### Types pris en charge de `JOIN` {#select-join-types} - `INNER JOIN` (ou `JOIN`) - `LEFT JOIN` (ou `LEFT OUTER JOIN`) @@ -546,11 +546,11 @@ Voir la norme [SQL JOIN](https://en.wikipedia.org/wiki/Join_(SQL)) Description. #### Plusieurs REJOINDRE {#multiple-join} -En effectuant des requêtes, ClickHouse réécrit les jointures multi-tables dans la séquence des jointures à deux tables. Par exemple, S’il y a quatre tables pour join clickhouse rejoint la première et la seconde, puis rejoint le résultat avec la troisième table, et à la dernière étape, il rejoint la quatrième. +En effectuant des requêtes, ClickHouse réécrit les jointures multi-tables dans la séquence des jointures à deux tables. Par exemple, S'il y a quatre tables pour join clickhouse rejoint la première et la seconde, puis rejoint le résultat avec la troisième table, et à la dernière étape, il rejoint la quatrième. -Si une requête contient l’ `WHERE` clickhouse essaie de pousser les filtres de cette clause à travers la jointure intermédiaire. S’il ne peut pas appliquer le filtre à chaque jointure intermédiaire, ClickHouse applique les filtres une fois toutes les jointures terminées. +Si une requête contient l' `WHERE` clickhouse essaie de pousser les filtres de cette clause à travers la jointure intermédiaire. S'il ne peut pas appliquer le filtre à chaque jointure intermédiaire, ClickHouse applique les filtres une fois toutes les jointures terminées. -Nous recommandons l’ `JOIN ON` ou `JOIN USING` syntaxe pour créer des requêtes. Exemple: +Nous recommandons l' `JOIN ON` ou `JOIN USING` syntaxe pour créer des requêtes. Exemple: ``` sql SELECT * FROM t1 JOIN t2 ON t1.a = t2.a JOIN t3 ON t1.a = t3.a @@ -564,19 +564,19 @@ SELECT * FROM t1, t2, t3 WHERE t1.a = t2.a AND t1.a = t3.a Ne mélangez pas ces syntaxes. -ClickHouse ne supporte pas directement la syntaxe avec des virgules, Nous ne recommandons donc pas de les utiliser. L’algorithme tente de réécrire la requête en termes de `CROSS JOIN` et `INNER JOIN` clauses et procède ensuite au traitement des requêtes. Lors de la réécriture de la requête, ClickHouse tente d’optimiser les performances et la consommation de mémoire. Par défaut, ClickHouse traite les virgules comme `INNER JOIN` clause et convertit `INNER JOIN` de `CROSS JOIN` lorsque l’algorithme ne peut pas garantir que `INNER JOIN` retourne les données requises. +ClickHouse ne supporte pas directement la syntaxe avec des virgules, Nous ne recommandons donc pas de les utiliser. L'algorithme tente de réécrire la requête en termes de `CROSS JOIN` et `INNER JOIN` clauses et procède ensuite au traitement des requêtes. Lors de la réécriture de la requête, ClickHouse tente d'optimiser les performances et la consommation de mémoire. Par défaut, ClickHouse traite les virgules comme `INNER JOIN` clause et convertit `INNER JOIN` de `CROSS JOIN` lorsque l'algorithme ne peut pas garantir que `INNER JOIN` retourne les données requises. #### Rigueur {#select-join-strictness} -- `ALL` — If the right table has several matching rows, ClickHouse creates a [Produit cartésien](https://en.wikipedia.org/wiki/Cartesian_product) à partir des lignes correspondantes. C’est la norme `JOIN` comportement en SQL. +- `ALL` — If the right table has several matching rows, ClickHouse creates a [Produit cartésien](https://en.wikipedia.org/wiki/Cartesian_product) à partir des lignes correspondantes. C'est la norme `JOIN` comportement en SQL. - `ANY` — If the right table has several matching rows, only the first one found is joined. If the right table has only one matching row, the results of queries with `ANY` et `ALL` les mots clés sont les mêmes. -- `ASOF` — For joining sequences with a non-exact match. `ASOF JOIN` l’utilisation est décrite ci-dessous. +- `ASOF` — For joining sequences with a non-exact match. `ASOF JOIN` l'utilisation est décrite ci-dessous. -**ASOF joindre L’utilisation** +**ASOF joindre L'utilisation** -`ASOF JOIN` est utile lorsque vous devez joindre des enregistrements qui n’ont pas de correspondance exacte. +`ASOF JOIN` est utile lorsque vous devez joindre des enregistrements qui n'ont pas de correspondance exacte. -Tables pour `ASOF JOIN` doit avoir une colonne de séquence ordonnée. Cette colonne ne peut pas être seule dans une table et doit être l’un des types de données: `UInt32`, `UInt64`, `Float32`, `Float64`, `Date`, et `DateTime`. +Tables pour `ASOF JOIN` doit avoir une colonne de séquence ordonnée. Cette colonne ne peut pas être seule dans une table et doit être l'un des types de données: `UInt32`, `UInt64`, `Float32`, `Float64`, `Date`, et `DateTime`. Syntaxe `ASOF JOIN ... ON`: @@ -587,7 +587,7 @@ ASOF LEFT JOIN table_2 ON equi_cond AND closest_match_cond ``` -Vous pouvez utiliser n’importe quel nombre de conditions d’égalité et exactement une condition de correspondance la plus proche. Exemple, `SELECT count() FROM table_1 ASOF LEFT JOIN table_2 ON table_1.a == table_2.b AND table_2.t <= table_1.t`. +Vous pouvez utiliser n'importe quel nombre de conditions d'égalité et exactement une condition de correspondance la plus proche. Exemple, `SELECT count() FROM table_1 ASOF LEFT JOIN table_2 ON table_1.a == table_2.b AND table_2.t <= table_1.t`. Conditions prises en charge pour la correspondance la plus proche: `>`, `>=`, `<`, `<=`. @@ -600,11 +600,780 @@ ASOF JOIN table_2 USING (equi_column1, ... equi_columnN, asof_column) ``` -`ASOF JOIN` utiliser `equi_columnX` pour rejoindre sur l’égalité et `asof_column` pour rejoindre le match le plus proche avec le `table_1.asof_column >= table_2.asof_column` condition. Le `asof_column` colonne toujours la dernière dans le `USING` clause. +`ASOF JOIN` utiliser `equi_columnX` pour rejoindre sur l'égalité et `asof_column` pour rejoindre le match le plus proche avec le `table_1.asof_column >= table_2.asof_column` condition. Le `asof_column` colonne toujours la dernière dans le `USING` clause. Par exemple, considérez les tableaux suivants: -\`\`\` texte -table\_1 table\_2 + table_1 table_2 + event | ev_time | user_id event | ev_time | user_id + ----------|---------|---------- ----------|---------|---------- + ... ... + event_1_1 | 12:00 | 42 event_2_1 | 11:59 | 42 + ... event_2_2 | 12:30 | 42 + event_1_2 | 13:00 | 42 event_2_3 | 13:00 | 42 + ... ... -événement \| ev\_time \| user\_id événement \| ev\_time \| user\_id +`ASOF JOIN` peut prendre la date d'un événement utilisateur de `table_1` et trouver un événement dans `table_2` où le timestamp est plus proche de l'horodatage de l'événement à partir de `table_1` correspondant à la condition de correspondance la plus proche. Les valeurs d'horodatage égales sont les plus proches si elles sont disponibles. Ici, l' `user_id` la colonne peut être utilisée pour joindre sur l'égalité et le `ev_time` la colonne peut être utilisée pour se joindre à la correspondance la plus proche. Dans notre exemple, `event_1_1` peut être jointe à `event_2_1` et `event_1_2` peut être jointe à `event_2_3`, mais `event_2_2` ne peut pas être rejoint. + +!!! note "Note" + `ASOF` jointure est **pas** pris en charge dans le [Rejoindre](../../engines/table-engines/special/join.md) tableau moteur. + +Pour définir la valeur de rigueur par défaut, utilisez le paramètre de configuration de session [join\_default\_strictness](../../operations/settings/settings.md#settings-join_default_strictness). + +#### GLOBAL JOIN {#global-join} + +Lors de l'utilisation normale `JOIN` la requête est envoyée aux serveurs distants. Les sous-requêtes sont exécutées sur chacune d'elles afin de créer la bonne table, et la jointure est effectuée avec cette table. En d'autres termes, la table de droite est formée sur chaque serveur séparément. + +Lors de l'utilisation de `GLOBAL ... JOIN`, d'abord le serveur demandeur exécute une sous-requête pour calculer la bonne table. Cette table temporaire est transmise à chaque serveur distant, et les requêtes sont exécutées sur eux en utilisant les données temporaires qui ont été transmises. + +Soyez prudent lorsque vous utilisez `GLOBAL`. Pour plus d'informations, consultez la section [Sous-requêtes distribuées](#select-distributed-subqueries). + +#### Recommandations D'Utilisation {#usage-recommendations} + +Lors de l'exécution d'un `JOIN`, il n'y a pas d'optimisation de la commande d'exécution par rapport aux autres stades de la requête. La jointure (une recherche dans la table de droite) est exécutée avant de filtrer `WHERE` et avant l'agrégation. Afin de définir explicitement l'ordre de traitement, nous vous recommandons d'exécuter une `JOIN` sous-requête avec une sous-requête. + +Exemple: + +``` sql +SELECT + CounterID, + hits, + visits +FROM +( + SELECT + CounterID, + count() AS hits + FROM test.hits + GROUP BY CounterID +) ANY LEFT JOIN +( + SELECT + CounterID, + sum(Sign) AS visits + FROM test.visits + GROUP BY CounterID +) USING CounterID +ORDER BY hits DESC +LIMIT 10 +``` + +``` text +┌─CounterID─┬───hits─┬─visits─┐ +│ 1143050 │ 523264 │ 13665 │ +│ 731962 │ 475698 │ 102716 │ +│ 722545 │ 337212 │ 108187 │ +│ 722889 │ 252197 │ 10547 │ +│ 2237260 │ 196036 │ 9522 │ +│ 23057320 │ 147211 │ 7689 │ +│ 722818 │ 90109 │ 17847 │ +│ 48221 │ 85379 │ 4652 │ +│ 19762435 │ 77807 │ 7026 │ +│ 722884 │ 77492 │ 11056 │ +└───────────┴────────┴────────┘ +``` + +Les sous-requêtes ne vous permettent pas de définir des noms ou de les utiliser pour référencer une colonne à partir d'une sous-requête spécifique. +Les colonnes spécifiées dans `USING` doit avoir les mêmes noms dans les deux sous-requêtes, et les autres colonnes doivent être nommées différemment. Vous pouvez utiliser des alias pour les noms des colonnes dans les sous-requêtes (l'exemple utilise l'alias `hits` et `visits`). + +Le `USING` clause spécifie une ou plusieurs colonnes de jointure, qui établit l'égalité de ces colonnes. La liste des colonnes est définie sans crochets. Les conditions de jointure plus complexes ne sont pas prises en charge. + +La table de droite (le résultat de la sous-requête) réside dans la RAM. S'il n'y a pas assez de mémoire, vous ne pouvez pas exécuter un `JOIN`. + +Chaque fois qu'une requête est exécutée avec la même `JOIN`, la sous-requête est exécutée à nouveau car le résultat n'est pas mis en cache. Pour éviter cela, utilisez la spéciale [Rejoindre](../../engines/table-engines/special/join.md) table engine, qui est un tableau préparé pour l'assemblage qui est toujours en RAM. + +Dans certains cas, il est plus efficace d'utiliser `IN` plutôt `JOIN`. +Parmi les différents types de `JOIN`, le plus efficace est d' `ANY LEFT JOIN`, puis `ANY INNER JOIN`. Les moins efficaces sont `ALL LEFT JOIN` et `ALL INNER JOIN`. + +Si vous avez besoin d'un `JOIN` pour se joindre à des tables de dimension (ce sont des tables relativement petites qui contiennent des propriétés de dimension, telles que des noms pour des campagnes publicitaires), un `JOIN` peut-être pas très pratique en raison du fait que la bonne table est ré-accédée pour chaque requête. Pour de tels cas, il y a un “external dictionaries” la fonctionnalité que vous devez utiliser à la place de `JOIN`. Pour plus d'informations, consultez la section [Dictionnaires externes](../dictionaries/external-dictionaries/external-dicts.md). + +**Limitations De Mémoire** + +ClickHouse utilise le [jointure de hachage](https://en.wikipedia.org/wiki/Hash_join) algorithme. ClickHouse prend le `` et crée une table de hachage pour cela dans la RAM. Si vous devez restreindre la consommation de mémoire de l'opération join utilisez les paramètres suivants: + +- [max\_rows\_in\_join](../../operations/settings/query-complexity.md#settings-max_rows_in_join) — Limits number of rows in the hash table. +- [max\_bytes\_in\_join](../../operations/settings/query-complexity.md#settings-max_bytes_in_join) — Limits size of the hash table. + +Lorsque l'une de ces limites est atteinte, ClickHouse agit comme [join\_overflow\_mode](../../operations/settings/query-complexity.md#settings-join_overflow_mode) réglage des instructions. + +#### Traitement des cellules vides ou nulles {#processing-of-empty-or-null-cells} + +Lors de la jonction de tables, les cellules vides peuvent apparaître. Paramètre [join\_use\_nulls](../../operations/settings/settings.md#join_use_nulls) définir comment clickhouse remplit ces cellules. + +Si l' `JOIN` les touches sont [Nullable](../data-types/nullable.md) champs, les lignes où au moins une des clés a la valeur [NULL](../syntax.md#null-literal) ne sont pas jointes. + +#### Limitations De Syntaxe {#syntax-limitations} + +Pour plusieurs `JOIN` clauses dans un seul `SELECT` requête: + +- Prendre toutes les colonnes via `*` n'est disponible que si les tables sont jointes, pas les sous-requêtes. +- Le `PREWHERE` la clause n'est pas disponible. + +Pour `ON`, `WHERE`, et `GROUP BY` clause: + +- Les expressions arbitraires ne peuvent pas être utilisées dans `ON`, `WHERE`, et `GROUP BY` mais vous pouvez définir une expression dans un `SELECT` clause et ensuite l'utiliser dans ces clauses via un alias. + +### Clause where {#select-where} + +S'il existe une clause WHERE, elle doit contenir une expression de type UInt8. C'est généralement une expression avec comparaison et opérateurs logiques. +Cette expression est utilisée pour filtrer les données avant toutes les autres transformations. + +Si les index sont pris en charge par le moteur de table de base de données, l'expression est évaluée sur la possibilité d'utiliser des index. + +### Clause PREWHERE {#prewhere-clause} + +Cette clause a le même sens que la clause WHERE. La différence est dans laquelle les données sont lues à partir de la table. +Lors de L'utilisation de PREWHERE, d'abord, seules les colonnes nécessaires à L'exécution de PREWHERE sont lues. Ensuite, les autres colonnes sont lues qui sont nécessaires pour exécuter la requête, mais seulement les blocs où L'expression PREWHERE est vraie. + +Il est logique d'utiliser PREWHERE s'il existe des conditions de filtration qui sont utilisées par une minorité de colonnes dans la requête, mais qui fournissent une filtration de données forte. Cela réduit le volume de données à lire. + +Par exemple, il est utile d'écrire PREWHERE pour les requêtes qui extraient un grand nombre de colonnes, mais qui n'ont que la filtration pour quelques colonnes. + +PREWHERE est uniquement pris en charge par les tables `*MergeTree` famille. + +Une requête peut spécifier simultanément PREWHERE et WHERE. Dans ce cas, PREWHERE précède WHERE. + +Si l' ‘optimize\_move\_to\_prewhere’ le paramètre est défini sur 1 et PREWHERE est omis, le système utilise des heuristiques pour déplacer automatiquement des parties d'expressions D'où vers PREWHERE. + +### Clause GROUP BY {#select-group-by-clause} + +C'est l'une des parties les plus importantes d'un SGBD orienté colonne. + +S'il existe une clause GROUP BY, elle doit contenir une liste d'expressions. Chaque expression sera appelée ici comme “key”. +Toutes les expressions des clauses SELECT, HAVING et ORDER BY doivent être calculées à partir de clés ou de fonctions d'agrégation. En d'autres termes, chaque colonne sélectionnée dans la table doit être utilisée soit dans les clés, soit dans les fonctions d'agrégation. + +Si une requête ne contient que des colonnes de table dans les fonctions d'agrégation, la clause GROUP BY peut être omise et l'agrégation par un ensemble de clés vide est supposée. + +Exemple: + +``` sql +SELECT + count(), + median(FetchTiming > 60 ? 60 : FetchTiming), + count() - sum(Refresh) +FROM hits +``` + +Cependant, contrairement au SQL standard, si la table n'a pas de lignes (soit il n'y en a pas du tout, soit il n'y en a pas après avoir utilisé WHERE to filter), un résultat vide est renvoyé, et non le résultat d'une des lignes contenant les valeurs initiales des fonctions d'agrégat. + +Contrairement à MySQL (et conforme à SQL standard), vous ne pouvez pas obtenir une valeur d'une colonne qui n'est pas dans une fonction clé ou agrégée (sauf les expressions constantes). Pour contourner ce problème, vous pouvez utiliser le ‘any’ fonction d'agrégation (récupère la première valeur rencontrée) ou ‘min/max’. + +Exemple: + +``` sql +SELECT + domainWithoutWWW(URL) AS domain, + count(), + any(Title) AS title -- getting the first occurred page header for each domain. +FROM hits +GROUP BY domain +``` + +Pour chaque valeur de clé différente rencontrée, GROUP BY calcule un ensemble de valeurs de fonction d'agrégation. + +GROUP BY n'est pas pris en charge pour les colonnes de tableau. + +Une constante ne peut pas être spécifiée comme arguments pour les fonctions d'agrégation. Exemple: somme(1). Au lieu de cela, vous pouvez vous débarrasser de la constante. Exemple: `count()`. + +#### Le Traitement NULL {#null-processing} + +Pour le regroupement, ClickHouse interprète [NULL](../syntax.md) comme une valeur, et `NULL=NULL`. + +Voici un exemple pour montrer ce que cela signifie. + +Supposons que vous avez cette table: + +``` text +┌─x─┬────y─┐ +│ 1 │ 2 │ +│ 2 │ ᴺᵁᴸᴸ │ +│ 3 │ 2 │ +│ 3 │ 3 │ +│ 3 │ ᴺᵁᴸᴸ │ +└───┴──────┘ +``` + +Requête `SELECT sum(x), y FROM t_null_big GROUP BY y` résultats dans: + +``` text +┌─sum(x)─┬────y─┐ +│ 4 │ 2 │ +│ 3 │ 3 │ +│ 5 │ ᴺᵁᴸᴸ │ +└────────┴──────┘ +``` + +Vous pouvez voir que `GROUP BY` pour `y = NULL` résumer `x` comme si `NULL` a cette valeur. + +Si vous passez plusieurs clés `GROUP BY` le résultat vous donnera toutes les combinaisons de la sélection, comme si `NULL` ont une valeur spécifique. + +#### Avec modificateur de totaux {#with-totals-modifier} + +Si le modificateur avec totaux est spécifié, une autre ligne sera calculée. Cette ligne aura des colonnes clés contenant des valeurs par défaut (zéros ou lignes vides), et des colonnes de fonctions d'agrégat avec les valeurs calculées sur toutes les lignes (le “total” valeur). + +Cette ligne supplémentaire est sortie dans les formats JSON\*, TabSeparated\* et Pretty\*, séparément des autres lignes. Dans les autres formats, cette ligne n'est pas sortie. + +Dans les formats JSON\*, cette ligne est sortie en tant que ‘totals’ champ. Dans les formats TabSeparated\*, la ligne vient après le résultat principal, précédée d'une ligne vide (après les autres données). Dans les formats Pretty\*, la ligne est sortie sous forme de table séparée après le résultat principal. + +`WITH TOTALS` peut être exécuté de différentes manières lorsqu'il est présent. Le comportement dépend de l' ‘totals\_mode’ paramètre. +Par défaut, `totals_mode = 'before_having'`. Dans ce cas, ‘totals’ est calculé sur toutes les lignes, y compris celles qui ne passent pas par ‘max\_rows\_to\_group\_by’. + +Les autres alternatives incluent uniquement les lignes qui passent à travers avoir dans ‘totals’, et se comporter différemment avec le réglage `max_rows_to_group_by` et `group_by_overflow_mode = 'any'`. + +`after_having_exclusive` – Don't include rows that didn't pass through `max_rows_to_group_by`. En d'autres termes, ‘totals’ aura moins ou le même nombre de lignes que si `max_rows_to_group_by` ont été omis. + +`after_having_inclusive` – Include all the rows that didn't pass through ‘max\_rows\_to\_group\_by’ dans ‘totals’. En d'autres termes, ‘totals’ aura plus ou le même nombre de lignes que si `max_rows_to_group_by` ont été omis. + +`after_having_auto` – Count the number of rows that passed through HAVING. If it is more than a certain amount (by default, 50%), include all the rows that didn't pass through ‘max\_rows\_to\_group\_by’ dans ‘totals’. Sinon, ne pas les inclure. + +`totals_auto_threshold` – By default, 0.5. The coefficient for `after_having_auto`. + +Si `max_rows_to_group_by` et `group_by_overflow_mode = 'any'` ne sont pas utilisés, toutes les variations de `after_having` sont les mêmes, et vous pouvez utiliser l'un d'eux (par exemple, `after_having_auto`). + +Vous pouvez utiliser avec les totaux dans les sous-requêtes, y compris les sous-requêtes dans la clause JOIN (dans ce cas, les valeurs totales respectives sont combinées). + +#### Groupe par dans la mémoire externe {#select-group-by-in-external-memory} + +Vous pouvez activer le dumping des données temporaires sur le disque pour limiter l'utilisation de la mémoire pendant `GROUP BY`. +Le [max\_bytes\_before\_external\_group\_by](../../operations/settings/settings.md#settings-max_bytes_before_external_group_by) réglage détermine le seuil de consommation de RAM pour le dumping `GROUP BY` données temporaires dans le système de fichiers. Si elle est définie sur 0 (valeur par défaut), elle est désactivée. + +Lors de l'utilisation de `max_bytes_before_external_group_by`, nous vous recommandons de définir `max_memory_usage` environ deux fois plus élevé. Ceci est nécessaire car il y a deux étapes à l'agrégation: la lecture de la date et la formation des données intermédiaires (1) et la fusion des données intermédiaires (2). Le Dumping des données dans le système de fichiers ne peut se produire qu'au cours de l'étape 1. Si les données temporaires n'ont pas été vidées, l'étape 2 peut nécessiter jusqu'à la même quantité de mémoire qu'à l'étape 1. + +Par exemple, si [max\_memory\_usage](../../operations/settings/settings.md#settings_max_memory_usage) a été défini sur 10000000000 et que vous souhaitez utiliser l'agrégation externe, il est logique de définir `max_bytes_before_external_group_by` à 10000000000, et max\_memory\_usage à 20000000000. Lorsque l'agrégation externe est déclenchée (s'il y a eu au moins un vidage de données temporaires), la consommation maximale de RAM n'est que légèrement supérieure à `max_bytes_before_external_group_by`. + +Avec le traitement des requêtes distribuées, l'agrégation externe est effectuée sur des serveurs distants. Pour que le serveur demandeur n'utilise qu'une petite quantité de RAM, définissez `distributed_aggregation_memory_efficient` 1. + +Lors de la fusion de données vidées sur le disque, ainsi que lors de la fusion des résultats de serveurs distants lorsque `distributed_aggregation_memory_efficient` paramètre est activé, consomme jusqu'à `1/256 * the_number_of_threads` à partir de la quantité totale de mémoire RAM. + +Lorsque l'agrégation externe est activée, s'il y a moins de `max_bytes_before_external_group_by` of data (i.e. data was not flushed), the query runs just as fast as without external aggregation. If any temporary data was flushed, the run time will be several times longer (approximately three times). + +Si vous avez un `ORDER BY` avec un `LIMIT` après `GROUP BY` puis la quantité de RAM dépend de la quantité de données dans `LIMIT`, pas dans l'ensemble de la table. Mais si l' `ORDER BY` n'a pas `LIMIT`, n'oubliez pas d'activer externe de tri (`max_bytes_before_external_sort`). + +### Limite par Clause {#limit-by-clause} + +Une requête avec l' `LIMIT n BY expressions` la clause sélectionne le premier `n` lignes pour chaque valeur distincte de `expressions`. La clé pour `LIMIT BY` peut contenir n'importe quel nombre de [expression](../syntax.md#syntax-expressions). + +ClickHouse prend en charge la syntaxe suivante: + +- `LIMIT [offset_value, ]n BY expressions` +- `LIMIT n OFFSET offset_value BY expressions` + +Pendant le traitement de la requête, ClickHouse sélectionne les données classées par clé de tri. La clé de tri est définie explicitement à l'aide [ORDER BY](#select-order-by) clause ou implicitement en tant que propriété du moteur de table. Puis clickhouse s'applique `LIMIT n BY expressions` et renvoie le premier `n` lignes pour chaque combinaison distincte de `expressions`. Si `OFFSET` est spécifié, puis pour chaque bloc de données qui appartient à une combinaison particulière de `expressions`, Clickhouse saute `offset_value` nombre de lignes depuis le début du bloc et renvoie un maximum de `n` les lignes en conséquence. Si `offset_value` est plus grand que le nombre de lignes dans le bloc de données, ClickHouse renvoie zéro lignes du bloc. + +`LIMIT BY` n'est pas liée à `LIMIT`. Ils peuvent tous deux être utilisés dans la même requête. + +**Exemple** + +Exemple de table: + +``` sql +CREATE TABLE limit_by(id Int, val Int) ENGINE = Memory; +INSERT INTO limit_by values(1, 10), (1, 11), (1, 12), (2, 20), (2, 21); +``` + +Requête: + +``` sql +SELECT * FROM limit_by ORDER BY id, val LIMIT 2 BY id +``` + +``` text +┌─id─┬─val─┐ +│ 1 │ 10 │ +│ 1 │ 11 │ +│ 2 │ 20 │ +│ 2 │ 21 │ +└────┴─────┘ +``` + +``` sql +SELECT * FROM limit_by ORDER BY id, val LIMIT 1, 2 BY id +``` + +``` text +┌─id─┬─val─┐ +│ 1 │ 11 │ +│ 1 │ 12 │ +│ 2 │ 21 │ +└────┴─────┘ +``` + +Le `SELECT * FROM limit_by ORDER BY id, val LIMIT 2 OFFSET 1 BY id` requête renvoie le même résultat. + +La requête suivante renvoie les 5 principaux référents pour chaque `domain, device_type` paire avec un maximum de 100 lignes au total (`LIMIT n BY + LIMIT`). + +``` sql +SELECT + domainWithoutWWW(URL) AS domain, + domainWithoutWWW(REFERRER_URL) AS referrer, + device_type, + count() cnt +FROM hits +GROUP BY domain, referrer, device_type +ORDER BY cnt DESC +LIMIT 5 BY domain, device_type +LIMIT 100 +``` + +### Clause HAVING {#having-clause} + +Permet de filtrer le résultat reçu après GROUP BY, similaire à la clause WHERE. +Où et ayant diffèrent en ce que Où est effectué avant l'agrégation (GROUP BY), tout en ayant est effectué après. +Si l'agrégation n'est pas effectuée, HAVING ne peut pas être utilisé. + +### Clause ORDER BY {#select-order-by} + +La clause ORDER BY contient une liste d'expressions, qui peuvent chacune être affectées à DESC ou ASC (la direction de tri). Si la direction n'est pas spécifiée, ASC est supposé. ASC est trié dans l'ordre croissant, et DESC dans l'ordre décroissant. La direction de tri s'applique à une seule expression, pas à la liste entière. Exemple: `ORDER BY Visits DESC, SearchPhrase` + +Pour le tri par valeurs de chaîne, vous pouvez spécifier le classement (comparaison). Exemple: `ORDER BY SearchPhrase COLLATE 'tr'` - pour le tri par mot-clé dans l'ordre croissant, en utilisant l'alphabet turc, insensible à la casse, en supposant que les chaînes sont encodées en UTF-8. COLLATE peut être spécifié ou non pour chaque expression dans L'ordre par indépendamment. Si ASC ou DESC est spécifié, COLLATE est spécifié après. Lors de L'utilisation de COLLATE, le tri est toujours insensible à la casse. + +Nous recommandons uniquement D'utiliser COLLATE pour le tri final d'un petit nombre de lignes, car le tri avec COLLATE est moins efficace que le tri normal par octets. + +Les lignes qui ont des valeurs identiques pour la liste des expressions de tri sont sorties dans un ordre arbitraire, qui peut également être non déterministe (différent à chaque fois). +Si la clause ORDER BY est omise, l'ordre des lignes est également indéfini et peut également être non déterministe. + +`NaN` et `NULL` ordre de tri: + +- Avec le modificateur `NULLS FIRST` — First `NULL`, puis `NaN` puis d'autres valeurs. +- Avec le modificateur `NULLS LAST` — First the values, then `NaN`, puis `NULL`. +- Default — The same as with the `NULLS LAST` modificateur. + +Exemple: + +Pour la table + +``` text +┌─x─┬────y─┐ +│ 1 │ ᴺᵁᴸᴸ │ +│ 2 │ 2 │ +│ 1 │ nan │ +│ 2 │ 2 │ +│ 3 │ 4 │ +│ 5 │ 6 │ +│ 6 │ nan │ +│ 7 │ ᴺᵁᴸᴸ │ +│ 6 │ 7 │ +│ 8 │ 9 │ +└───┴──────┘ +``` + +Exécuter la requête `SELECT * FROM t_null_nan ORDER BY y NULLS FIRST` obtenir: + +``` text +┌─x─┬────y─┐ +│ 1 │ ᴺᵁᴸᴸ │ +│ 7 │ ᴺᵁᴸᴸ │ +│ 1 │ nan │ +│ 6 │ nan │ +│ 2 │ 2 │ +│ 2 │ 2 │ +│ 3 │ 4 │ +│ 5 │ 6 │ +│ 6 │ 7 │ +│ 8 │ 9 │ +└───┴──────┘ +``` + +Lorsque les nombres à virgule flottante sont triés, les Nan sont séparés des autres valeurs. Quel que soit l'ordre de tri, NaNs viennent à la fin. En d'autres termes, pour le Tri ascendant, ils sont placés comme s'ils étaient plus grands que tous les autres nombres, tandis que pour le Tri descendant, ils sont placés comme s'ils étaient plus petits que les autres. + +Moins de RAM est utilisé si une limite assez petite est spécifiée en plus de ORDER BY. Sinon, la quantité de mémoire dépensée est proportionnelle au volume de données à trier. Pour le traitement des requêtes distribuées, si GROUP BY est omis, le tri est partiellement effectué sur des serveurs distants et les résultats sont fusionnés sur le serveur demandeur. Cela signifie que pour le tri distribué, le volume de données à trier peut être supérieur à la quantité de mémoire sur un seul serveur. + +S'il N'y a pas assez de RAM, il est possible d'effectuer un tri dans la mémoire externe (création de fichiers temporaires sur un disque). Utilisez le paramètre `max_bytes_before_external_sort` pour ce but. S'il est défini sur 0 (par défaut), le tri externe est désactivé. Si elle est activée, lorsque le volume de données à trier atteint le nombre spécifié d'octets, les données collectées sont triés et déposés dans un fichier temporaire. Une fois toutes les données lues, tous les fichiers triés sont fusionnés et les résultats sont générés. Les fichiers sont écrits dans le répertoire/var/lib / clickhouse / tmp / dans la configuration (par défaut, mais vous pouvez ‘tmp\_path’ paramètre pour modifier ce paramètre). + +L'exécution d'une requête peut utiliser plus de mémoire que ‘max\_bytes\_before\_external\_sort’. Pour cette raison, ce paramètre doit avoir une valeur significativement inférieure à ‘max\_memory\_usage’. Par exemple, si votre serveur dispose de 128 Go de RAM et que vous devez exécuter une seule requête, définissez ‘max\_memory\_usage’ à 100 Go, et ‘max\_bytes\_before\_external\_sort’ à 80 Go. + +Le tri externe fonctionne beaucoup moins efficacement que le tri dans la RAM. + +### Clause SELECT {#select-select} + +[Expression](../syntax.md#syntax-expressions) spécifié dans le `SELECT` clause sont calculés après toutes les opérations dans les clauses décrites ci-dessus sont terminés. Ces expressions fonctionnent comme si elles s'appliquaient à des lignes séparées dans le résultat. Si les expressions dans le `SELECT` la clause contient des fonctions d'agrégation, puis clickhouse traite les fonctions d'agrégation et les expressions utilisées [GROUP BY](#select-group-by-clause) agrégation. + +Si vous souhaitez inclure toutes les colonnes dans le résultat, utilisez l'astérisque (`*`) symbole. Exemple, `SELECT * FROM ...`. + +Pour correspondre à certaines colonnes dans le résultat avec un [re2](https://en.wikipedia.org/wiki/RE2_(software)) expression régulière, vous pouvez utiliser le `COLUMNS` expression. + +``` sql +COLUMNS('regexp') +``` + +Par exemple, considérez le tableau: + +``` sql +CREATE TABLE default.col_names (aa Int8, ab Int8, bc Int8) ENGINE = TinyLog +``` + +La requête suivante sélectionne les données de toutes les colonnes contenant les `a` symbole dans leur nom. + +``` sql +SELECT COLUMNS('a') FROM col_names +``` + +``` text +┌─aa─┬─ab─┐ +│ 1 │ 1 │ +└────┴────┘ +``` + +Les colonnes sélectionnées sont retournés pas dans l'ordre alphabétique. + +Vous pouvez utiliser plusieurs `COLUMNS` expressions dans une requête et leur appliquer des fonctions. + +Exemple: + +``` sql +SELECT COLUMNS('a'), COLUMNS('c'), toTypeName(COLUMNS('c')) FROM col_names +``` + +``` text +┌─aa─┬─ab─┬─bc─┬─toTypeName(bc)─┐ +│ 1 │ 1 │ 1 │ Int8 │ +└────┴────┴────┴────────────────┘ +``` + +Chaque colonne renvoyée par le `COLUMNS` expression est passée à la fonction en tant qu'argument séparé. Vous pouvez également passer d'autres arguments à la fonction si elle les supporte. Soyez prudent lorsque vous utilisez des fonctions. Si une fonction ne prend pas en charge le nombre d'arguments que vous lui avez transmis, ClickHouse lève une exception. + +Exemple: + +``` sql +SELECT COLUMNS('a') + COLUMNS('c') FROM col_names +``` + +``` text +Received exception from server (version 19.14.1): +Code: 42. DB::Exception: Received from localhost:9000. DB::Exception: Number of arguments for function plus doesn't match: passed 3, should be 2. +``` + +Dans cet exemple, `COLUMNS('a')` retourne deux colonnes: `aa` et `ab`. `COLUMNS('c')` renvoie la `bc` colonne. Le `+` l'opérateur ne peut pas s'appliquer à 3 arguments, donc ClickHouse lève une exception avec le message pertinent. + +Colonnes qui correspondent à la `COLUMNS` l'expression peut avoir différents types de données. Si `COLUMNS` ne correspond à aucune colonne et est la seule expression dans `SELECT`, ClickHouse lance une exception. + +### La Clause DISTINCT {#select-distinct} + +Si DISTINCT est spécifié, une seule ligne restera hors de tous les ensembles de lignes entièrement correspondantes dans le résultat. +Le résultat sera le même que si GROUP BY était spécifié dans tous les champs spécifiés dans SELECT without aggregate functions. Mais il y a plusieurs différences de GROUP BY: + +- DISTINCT peut être appliqué avec GROUP BY. +- Lorsque ORDER BY est omis et que LIMIT est défini, la requête s'arrête immédiatement après la lecture du nombre requis de lignes différentes. +- Les blocs de données sont produits au fur et à mesure qu'ils sont traités, sans attendre que la requête entière se termine. + +DISTINCT n'est pas pris en charge si SELECT a au moins une colonne de tableau. + +`DISTINCT` fonctionne avec [NULL](../syntax.md) comme si `NULL` ont une valeur spécifique, et `NULL=NULL`. En d'autres termes, dans le `DISTINCT` résultats, différentes combinaisons avec `NULL` qu'une seule fois. + +Clickhouse prend en charge l'utilisation du `DISTINCT` et `ORDER BY` clauses pour différentes colonnes dans une requête. Le `DISTINCT` la clause est exécutée avant la `ORDER BY` clause. + +Exemple de table: + +``` text +┌─a─┬─b─┐ +│ 2 │ 1 │ +│ 1 │ 2 │ +│ 3 │ 3 │ +│ 2 │ 4 │ +└───┴───┘ +``` + +Lors de la sélection de données avec le `SELECT DISTINCT a FROM t1 ORDER BY b ASC` requête, nous obtenons le résultat suivant: + +``` text +┌─a─┐ +│ 2 │ +│ 1 │ +│ 3 │ +└───┘ +``` + +Si nous changeons la direction de tri `SELECT DISTINCT a FROM t1 ORDER BY b DESC`, nous obtenons le résultat suivant: + +``` text +┌─a─┐ +│ 3 │ +│ 1 │ +│ 2 │ +└───┘ +``` + +Rangée `2, 4` a été coupé avant de les trier. + +Prenez en compte cette spécificité d'implémentation lors de la programmation des requêtes. + +### Clause LIMIT {#limit-clause} + +`LIMIT m` vous permet de sélectionner la première `m` lignes du résultat. + +`LIMIT n, m` vous permet de sélectionner la première `m` lignes du résultat après avoir sauté le premier `n` rangée. Le `LIMIT m OFFSET n` la syntaxe est également prise en charge. + +`n` et `m` doivent être des entiers non négatifs. + +Si il n'y a pas un `ORDER BY` clause qui trie explicitement les résultats, le résultat peut être arbitraire et non déterministe. + +### Clause UNION ALL {#union-all-clause} + +Vous pouvez utiliser UNION ALL pour combiner n'importe quel nombre de requêtes. Exemple: + +``` sql +SELECT CounterID, 1 AS table, toInt64(count()) AS c + FROM test.hits + GROUP BY CounterID + +UNION ALL + +SELECT CounterID, 2 AS table, sum(Sign) AS c + FROM test.visits + GROUP BY CounterID + HAVING c > 0 +``` + +Seule UNION ALL est prise en charge. L'UNION régulière (Union distincte) n'est pas prise en charge. Si vous avez besoin D'UNION DISTINCT, vous pouvez écrire SELECT DISTINCT à partir d'une sous-requête contenant UNION ALL. + +Les requêtes qui font partie de L'UNION peuvent toutes être exécutées simultanément et leurs résultats peuvent être mélangés. + +La structure des résultats (le nombre et le type de colonnes) doit correspondre aux requêtes. Mais les noms des colonnes peuvent différer. Dans ce cas, les noms de colonne pour le résultat final seront tirés de la première requête. La coulée de Type est effectuée pour les syndicats. Par exemple, si deux requêtes combinées ont le même champ avec non-`Nullable` et `Nullable` types d'un type compatible, la `UNION ALL` a un `Nullable` type de champ. + +Les requêtes qui font partie de UNION ALL ne peuvent pas être placées entre crochets. ORDER BY et LIMIT sont appliqués à des requêtes distinctes, pas au résultat final. Si vous devez appliquer une conversion au résultat final, vous pouvez placer toutes les requêtes avec UNION ALL dans une sous-requête de la clause FROM. + +### Dans OUTFILE Clause {#into-outfile-clause} + +Ajouter l' `INTO OUTFILE filename` clause (où filename est un littéral de chaîne) pour rediriger la sortie de la requête vers le fichier spécifié. +Contrairement à MySQL, le fichier est créé du côté client. La requête échouera si un fichier portant le même nom existe déjà. +Cette fonctionnalité est disponible dans le client de ligne de commande et clickhouse-local (une requête envoyée via L'interface HTTP échouera). + +Le format de sortie par défaut est TabSeparated (le même que dans le mode batch client de ligne de commande). + +### FORMAT de la Clause {#format-clause} + +Spécifier ‘FORMAT format’ pour obtenir des données dans n'importe quel format spécifié. +Vous pouvez l'utiliser pour plus de commodité, ou pour créer des vidages. +Pour plus d'informations, consultez la section “Formats”. +Si la clause FORMAT est omise, le format par défaut est utilisé, ce qui dépend à la fois des paramètres et de l'interface utilisée pour accéder à la base de données. Pour L'interface HTTP et le client de ligne de commande en mode batch, le format par défaut est TabSeparated. Pour le client de ligne de commande en mode interactif, le format par défaut est PrettyCompact (il a des tables attrayantes et compactes). + +Lors de l'utilisation du client de ligne de commande, les données sont transmises au client dans un format efficace interne. Le client interprète indépendamment la clause de FORMAT de la requête et formate les données elles-mêmes (soulageant ainsi le réseau et le serveur de la charge). + +### Dans les opérateurs {#select-in-operators} + +Le `IN`, `NOT IN`, `GLOBAL IN`, et `GLOBAL NOT IN` les opérateurs sont traitées séparément, car leur fonctionnalité est assez riche. + +Le côté gauche de l'opérateur, soit une seule colonne ou un tuple. + +Exemple: + +``` sql +SELECT UserID IN (123, 456) FROM ... +SELECT (CounterID, UserID) IN ((34, 123), (101500, 456)) FROM ... +``` + +Si le côté gauche est une colonne unique qui est dans l'index, et le côté droit est un ensemble de constantes, le système utilise l'index pour le traitement de la requête. + +Don't list too many values explicitly (i.e. millions). If a data set is large, put it in a temporary table (for example, see the section “External data for query processing”), puis utiliser une sous-requête. + +Le côté droit de l'opérateur peut être un ensemble d'expressions constantes, un ensemble de tuples avec des expressions constantes (illustrées dans les exemples ci-dessus), ou le nom d'une table de base de données ou une sous-requête SELECT entre parenthèses. + +Si le côté droit de l'opérateur est le nom d'une table (par exemple, `UserID IN users`), ceci est équivalent à la sous-requête `UserID IN (SELECT * FROM users)`. Utilisez ceci lorsque vous travaillez avec des données externes envoyées avec la requête. Par exemple, la requête peut être envoyée avec un ensemble d'ID utilisateur chargés dans le ‘users’ table temporaire, qui doit être filtrée. + +Si le côté droit de l'opérateur est un nom de table qui a le moteur Set (un ensemble de données préparé qui est toujours en RAM), l'ensemble de données ne sera pas créé à nouveau pour chaque requête. + +La sous-requête peut spécifier plusieurs colonnes pour filtrer les tuples. +Exemple: + +``` sql +SELECT (CounterID, UserID) IN (SELECT CounterID, UserID FROM ...) FROM ... +``` + +Les colonnes à gauche et à droite de l'opérateur doit avoir le même type. + +L'opérateur IN et la sous-requête peuvent se produire dans n'importe quelle partie de la requête, y compris dans les fonctions d'agrégation et les fonctions lambda. +Exemple: + +``` sql +SELECT + EventDate, + avg(UserID IN + ( + SELECT UserID + FROM test.hits + WHERE EventDate = toDate('2014-03-17') + )) AS ratio +FROM test.hits +GROUP BY EventDate +ORDER BY EventDate ASC +``` + +``` text +┌──EventDate─┬────ratio─┐ +│ 2014-03-17 │ 1 │ +│ 2014-03-18 │ 0.807696 │ +│ 2014-03-19 │ 0.755406 │ +│ 2014-03-20 │ 0.723218 │ +│ 2014-03-21 │ 0.697021 │ +│ 2014-03-22 │ 0.647851 │ +│ 2014-03-23 │ 0.648416 │ +└────────────┴──────────┘ +``` + +Pour chaque jour après le 17 mars, comptez le pourcentage de pages vues par les utilisateurs qui ont visité le site le 17 mars. +Une sous-requête dans la clause est toujours exécuter une seule fois sur un seul serveur. Il n'y a pas de sous-requêtes dépendantes. + +#### Le Traitement NULL {#null-processing-1} + +Pendant le traitement de la demande, l'opérateur n'assume que le résultat d'une opération avec [NULL](../syntax.md) est toujours égale à `0` indépendamment de savoir si `NULL` est sur le côté droit ou gauche de l'opérateur. `NULL` les valeurs ne sont incluses dans aucun jeu de données, ne correspondent pas entre elles et ne peuvent pas être comparées. + +Voici un exemple avec le `t_null` table: + +``` text +┌─x─┬────y─┐ +│ 1 │ ᴺᵁᴸᴸ │ +│ 2 │ 3 │ +└───┴──────┘ +``` + +L'exécution de la requête `SELECT x FROM t_null WHERE y IN (NULL,3)` vous donne le résultat suivant: + +``` text +┌─x─┐ +│ 2 │ +└───┘ +``` + +Vous pouvez voir que la ligne dans laquelle `y = NULL` est jeté hors de résultats de la requête. C'est parce que ClickHouse ne peut pas décider si `NULL` est inclus dans le `(NULL,3)` ensemble, les retours `0` comme le résultat de l'opération, et `SELECT` exclut cette ligne de la sortie finale. + +``` sql +SELECT y IN (NULL, 3) +FROM t_null +``` + +``` text +┌─in(y, tuple(NULL, 3))─┐ +│ 0 │ +│ 1 │ +└───────────────────────┘ +``` + +#### Sous-Requêtes Distribuées {#select-distributed-subqueries} + +Il y a deux options pour IN-S avec des sous-requêtes (similaires aux jointures): normal `IN` / `JOIN` et `GLOBAL IN` / `GLOBAL JOIN`. Ils diffèrent dans la façon dont ils sont exécutés pour le traitement des requêtes distribuées. + +!!! attention "Attention" + Rappelez-vous que les algorithmes décrits ci-dessous peuvent travailler différemment en fonction de la [paramètre](../../operations/settings/settings.md) `distributed_product_mode` paramètre. + +Lors de l'utilisation de l'IN régulier, la requête est envoyée à des serveurs distants, et chacun d'eux exécute les sous-requêtes dans le `IN` ou `JOIN` clause. + +Lors de l'utilisation de `GLOBAL IN` / `GLOBAL JOINs`, d'abord toutes les sous-requêtes sont exécutées pour `GLOBAL IN` / `GLOBAL JOINs`, et les résultats sont recueillis dans des tableaux temporaires. Ensuite, les tables temporaires sont envoyés à chaque serveur distant, où les requêtes sont exécutées à l'aide temporaire de données. + +Pour une requête non distribuée, utilisez `IN` / `JOIN`. + +Soyez prudent lorsque vous utilisez des sous-requêtes dans le `IN` / `JOIN` clauses pour le traitement des requêtes distribuées. + +Regardons quelques exemples. Supposons que chaque serveur du cluster a un **local\_table**. Chaque serveur dispose également d'une **table distributed\_table** table avec le **Distribué** type, qui regarde tous les serveurs du cluster. + +Pour une requête à l' **table distributed\_table**, la requête sera envoyée à tous les serveurs distants et exécutée sur eux en utilisant le **local\_table**. + +Par exemple, la requête + +``` sql +SELECT uniq(UserID) FROM distributed_table +``` + +sera envoyé à tous les serveurs distants + +``` sql +SELECT uniq(UserID) FROM local_table +``` + +et l'exécuter sur chacun d'eux en parallèle, jusqu'à ce qu'il atteigne le stade où les résultats intermédiaires peuvent être combinés. Ensuite, les résultats intermédiaires seront retournés au demandeur de serveur et de fusion, et le résultat final sera envoyé au client. + +Examinons maintenant une requête avec IN: + +``` sql +SELECT uniq(UserID) FROM distributed_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM local_table WHERE CounterID = 34) +``` + +- Calcul de l'intersection des audiences de deux sites. + +Cette requête sera envoyée à tous les serveurs distants + +``` sql +SELECT uniq(UserID) FROM local_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM local_table WHERE CounterID = 34) +``` + +En d'autres termes, l'ensemble de données de la clause IN sera collecté sur chaque serveur indépendamment, uniquement à travers les données stockées localement sur chacun des serveurs. + +Cela fonctionnera correctement et de manière optimale si vous êtes prêt pour ce cas et que vous avez réparti les données entre les serveurs de cluster de telle sorte que les données d'un seul ID utilisateur résident entièrement sur un seul serveur. Dans ce cas, toutes les données nécessaires seront disponibles localement sur chaque serveur. Sinon, le résultat sera erroné. Nous nous référons à cette variation de la requête que “local IN”. + +Pour corriger le fonctionnement de la requête lorsque les données sont réparties aléatoirement sur les serveurs de cluster, vous pouvez spécifier **table distributed\_table** à l'intérieur d'une sous-requête. La requête ressemblerait à ceci: + +``` sql +SELECT uniq(UserID) FROM distributed_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM distributed_table WHERE CounterID = 34) +``` + +Cette requête sera envoyée à tous les serveurs distants + +``` sql +SELECT uniq(UserID) FROM local_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM distributed_table WHERE CounterID = 34) +``` + +La sous-requête commencera à s'exécuter sur chaque serveur distant. Étant donné que la sous-requête utilise une table distribuée, la sous-requête qui se trouve sur chaque serveur distant sera renvoyée à chaque serveur distant comme + +``` sql +SELECT UserID FROM local_table WHERE CounterID = 34 +``` + +Par exemple, si vous avez un cluster de 100 SERVEURS, l'exécution de la requête entière nécessitera 10 000 requêtes élémentaires, ce qui est généralement considéré comme inacceptable. + +Dans de tels cas, vous devez toujours utiliser GLOBAL IN au lieu de IN. Voyons comment cela fonctionne pour la requête + +``` sql +SELECT uniq(UserID) FROM distributed_table WHERE CounterID = 101500 AND UserID GLOBAL IN (SELECT UserID FROM distributed_table WHERE CounterID = 34) +``` + +Le serveur demandeur exécutera la sous requête + +``` sql +SELECT UserID FROM distributed_table WHERE CounterID = 34 +``` + +et le résultat sera mis dans une table temporaire en RAM. Ensuite, la demande sera envoyée à chaque serveur distant + +``` sql +SELECT uniq(UserID) FROM local_table WHERE CounterID = 101500 AND UserID GLOBAL IN _data1 +``` + +et la table temporaire `_data1` sera envoyé à chaque serveur distant avec la requête (le nom de la table temporaire est défini par l'implémentation). + +Ceci est plus optimal que d'utiliser la normale dans. Cependant, gardez les points suivants à l'esprit: + +1. Lors de la création d'une table temporaire, les données ne sont pas uniques. Pour réduire le volume de données transmises sur le réseau, spécifiez DISTINCT dans la sous-requête. (Vous n'avez pas besoin de le faire pour un IN normal.) +2. La table temporaire sera envoyé à tous les serveurs distants. La Transmission ne tient pas compte de la topologie du réseau. Par exemple, si 10 serveurs distants résident dans un centre de données très distant par rapport au serveur demandeur, les données seront envoyées 10 fois sur le canal au centre de données distant. Essayez d'éviter les grands ensembles de données lorsque vous utilisez GLOBAL IN. +3. Lors de la transmission de données à des serveurs distants, les restrictions sur la bande passante réseau ne sont pas configurables. Vous pourriez surcharger le réseau. +4. Essayez de distribuer les données entre les serveurs afin que vous n'ayez pas besoin D'utiliser GLOBAL IN sur une base régulière. +5. Si vous devez utiliser GLOBAL in souvent, planifiez l'emplacement du cluster ClickHouse de sorte qu'un seul groupe de répliques ne réside pas dans plus d'un centre de données avec un réseau rapide entre eux, de sorte qu'une requête puisse être traitée entièrement dans un seul centre de données. + +Il est également judicieux de spécifier une table locale dans le `GLOBAL IN` clause, dans le cas où cette table locale est uniquement disponible sur le serveur demandeur et que vous souhaitez utiliser les données de celui-ci sur des serveurs distants. + +### Les Valeurs Extrêmes {#extreme-values} + +En plus des résultats, vous pouvez également obtenir des valeurs minimales et maximales pour les colonnes de résultats. Pour ce faire, définissez la **extrême** réglage sur 1. Les Minimums et les maximums sont calculés pour les types numériques, les dates et les dates avec des heures. Pour les autres colonnes, les valeurs par défaut sont sorties. + +An extra two rows are calculated – the minimums and maximums, respectively. These extra two rows are output in `JSON*`, `TabSeparated*`, et `Pretty*` [format](../../interfaces/formats.md), séparés des autres lignes. Ils ne sont pas Produits pour d'autres formats. + +Dans `JSON*` formats, les valeurs extrêmes sont sorties dans un ‘extremes’ champ. Dans `TabSeparated*` formats, la ligne vient après le résultat principal, et après ‘totals’ si elle est présente. Elle est précédée par une ligne vide (après les autres données). Dans `Pretty*` formats, la ligne est sortie comme une table séparée après le résultat principal, et après `totals` si elle est présente. + +Les valeurs extrêmes sont calculées pour les lignes avant `LIMIT` mais après `LIMIT BY`. Cependant, lors de l'utilisation de `LIMIT offset, size`, les lignes avant de les `offset` sont inclus dans `extremes`. Dans les requêtes de flux, le résultat peut également inclure un petit nombre de lignes qui ont traversé `LIMIT`. + +### Note {#notes} + +Le `GROUP BY` et `ORDER BY` les clauses ne supportent pas les arguments positionnels. Cela contredit MySQL, mais est conforme à SQL standard. +Exemple, `GROUP BY 1, 2` will be interpreted as grouping by constants (i.e. aggregation of all rows into one). + +Vous pouvez utiliser des synonymes (`AS` alias) dans n'importe quelle partie d'une requête. + +Vous pouvez mettre un astérisque dans quelque partie de la requête au lieu d'une expression. Lorsque la requête est analysée, l'astérisque est étendu à une liste de toutes les colonnes `MATERIALIZED` et `ALIAS` colonne). Il n'y a que quelques cas où l'utilisation d'un astérisque est justifiée: + +- Lors de la création d'un vidage de table. +- Pour les tables contenant seulement quelques colonnes, comme les tables système. +- Pour obtenir des informations sur ce que sont les colonnes dans une table. Dans ce cas, la valeur `LIMIT 1`. Mais il est préférable d'utiliser la `DESC TABLE` requête. +- Quand il y a une forte filtration sur un petit nombre de colonnes en utilisant `PREWHERE`. +- Dans les sous-requêtes (puisque les colonnes qui ne sont pas nécessaires pour la requête externe sont exclues des sous-requêtes). + +Dans tous les autres cas, nous ne recommandons pas d'utiliser l'astérisque, car il ne vous donne que les inconvénients d'un SGBD colonnaire au lieu des avantages. En d'autres termes, l'utilisation de l'astérisque n'est pas recommandée. + +[Article Original](https://clickhouse.tech/docs/en/query_language/select/) diff --git a/docs/ja/sql-reference/statements/select.md b/docs/ja/sql-reference/statements/select.md index 4a643f9dcd9..6d67c329e07 100644 --- a/docs/ja/sql-reference/statements/select.md +++ b/docs/ja/sql-reference/statements/select.md @@ -1,6 +1,6 @@ --- machine_translated: true -machine_translated_rev: d734a8e46ddd7465886ba4133bff743c55190626 +machine_translated_rev: 0f7ef7704d018700049223525bad4a63911b6e70 toc_priority: 33 toc_title: SELECT --- @@ -32,7 +32,7 @@ SELECT直後の必須の式リストを除き、すべての句はオプショ 以下の句は、クエリ実行コンベアとほぼ同じ順序で記述されています。 クエリが省略された場合、 `DISTINCT`, `GROUP BY` と `ORDER BY` 句および `IN` と `JOIN` サブクエリでは、クエリはO(1)量のRAMを使用して完全にストリーム処理されます。 -それ以外の場合、適切な制限が指定されていない場合、クエリは大量のramを消費する可能性があります: `max_memory_usage`, `max_rows_to_group_by`, `max_rows_to_sort`, `max_rows_in_distinct`, `max_bytes_in_distinct`, `max_rows_in_set`, `max_bytes_in_set`, `max_rows_in_join`, `max_bytes_in_join`, `max_bytes_before_external_sort`, `max_bytes_before_external_group_by`. 詳細については、以下を参照してください “Settings”. 外部ソート(一時テーブルをディスクに保存する)と外部集約を使用することが可能です。 `The system does not have "merge join"`. +それ以外の場合、適切な制限が指定されていない場合、クエリは大量のRAMを消費する可能性があります: `max_memory_usage`, `max_rows_to_group_by`, `max_rows_to_sort`, `max_rows_in_distinct`, `max_bytes_in_distinct`, `max_rows_in_set`, `max_bytes_in_set`, `max_rows_in_join`, `max_bytes_in_join`, `max_bytes_before_external_sort`, `max_bytes_before_external_group_by`. 詳細については、以下を参照してください “Settings”. 外部ソート(一時テーブルをディスクに保存する)と外部集約を使用することが可能です。 `The system does not have "merge join"`. ### With句 {#with-clause} @@ -53,7 +53,7 @@ WHERE EventTime <= ts_upper_bound ``` -例2:select句の列リストからsum(bytes)式の結果を削除する +例2:SELECT句の列リストからsum(bytes)式の結果を削除する ``` sql WITH sum(bytes) as s @@ -65,7 +65,7 @@ GROUP BY table ORDER BY s ``` -例3:結果のスカラサブクエリ +例3:スカラーサブクエリの結果の使用 ``` sql /* this example would return TOP 10 of most huge tables */ @@ -119,9 +119,9 @@ FROM句が省略された場合、データは `system.one` テーブル。 `ARRAY JOIN` そして、定期的に `JOIN` また、(下記参照)が含まれていてもよいです。 テーブルの代わりに、 `SELECT` サブクエリは、かっこで指定できます。 -標準sqlとは対照的に、サブクエリの後にシノニムを指定する必要はありません。 +標準SQLとは対照的に、サブクエリの後にシノニムを指定する必要はありません。 -実行をクエリに対して、すべての列をクエリを取り出しに適します。 任意の列は不要のため、外部クエリはスローされ、サブクエリ. +クエリを実行するには、クエリにリストされているすべての列を適切なテーブルから抽出します。 外部クエリに必要のない列は、サブクエリからスローされます。 クエリで列がリストされない場合(たとえば, `SELECT count() FROM t`)行の数を計算するために、いくつかの列がテーブルから抽出されます(最小の列が優先されます)。 #### 最終修飾子 {#select-from-final} @@ -157,7 +157,7 @@ FROM句が省略された場合、データは `system.one` テーブル。 データサンプリングの機能を以下に示します: - データサンプリングは確定的なメカニズムです。 同じの結果 `SELECT .. SAMPLE` クエリは常に同じです。 -- サンプリン テーブルに単一のサンプリングキーは、サンプルと同じ係数を常に選択と同じサブセットのデータです。 たとえば、ユーザー idのサンプルでは、異なるテーブルのすべてのユーザー idのサブセットが同じ行になります。 これは、サブクエリでサンプルを使用できることを意味します [IN](#select-in-operators) 句。 また、以下を使用してサンプルを結合できます [JOIN](#select-join) 句。 +- サンプリン テーブルに単一のサンプリングキーは、サンプルと同じ係数を常に選択と同じサブセットのデータです。 たとえば、ユーザー Idのサンプルでは、異なるテーブルのすべてのユーザー Idのサブセットが同じ行になります。 これは、サブクエリでサンプルを使用できることを意味します [IN](#select-in-operators) 句。 また、以下を使用してサンプルを結合できます [JOIN](#select-join) 句。 - サンプリングで読み下からのデータディスク。 サンプリングキーを正しく指定する必要があります。 詳細については、 [MergeTreeテーブルの作成](../../engines/table-engines/mergetree-family/mergetree.md#table_engine-mergetree-creating-a-table). のための `SAMPLE` 句次の構文がサポートされています: @@ -250,7 +250,7 @@ SAMPLE 1/10 OFFSET 1/2 ### 配列結合句 {#select-array-join-clause} -実行を許可する `JOIN` 配列または入れ子になったデータ構造。 その意図は、 [arrayJoin](../../sql-reference/functions/array-join.md#functions_arrayjoin) 機能が、その機能はより広いです。 +実行を許可する `JOIN` 配列または入れ子になったデータ構造。 その意図は、 [arrayJoin](../functions/array-join.md#functions_arrayjoin) 機能が、その機能はより広いです。 ``` sql SELECT @@ -407,7 +407,7 @@ ARRAY JOIN arr AS a, arrayEnumerate(arr) AS num; #### 配列の参加入れ子データ構造 {#array-join-with-nested-data-structure} -`ARRAY`また、“参加”で動作します [入れ子のデータ構造](../../sql-reference/data-types/nested-data-structures/nested.md). 例えば: +`ARRAY`また、"参加"で動作します [入れ子のデータ構造](../../sql-reference/data-types/nested-data-structures/nested.md). 例えば: ``` sql CREATE TABLE nested_test @@ -546,7 +546,7 @@ FROM #### 複数の結合 {#multiple-join} -クエリを実行すると、clickhouseはマルチテーブル結合を二つのテーブル結合のシーケンスに書き換えます。 たとえば、clickhouseに参加するための四つのテーブルがある場合は、最初と二番目のテーブルを結合し、その結果を三番目のテーブルに結合し、最後のステップで +クエリを実行すると、ClickHouseはマルチテーブル結合を二つのテーブル結合のシーケンスに書き換えます。 たとえば、clickhouseに参加するための四つのテーブルがある場合は、最初と二番目のテーブルを結合し、その結果を三番目のテーブルに結合し、最後のステップで クエリが含まれている場合、 `WHERE` 句、ClickHouseはこの句から中間結合を介してプッシュダウンフィルターを試行します。 各中間結合にフィルタを適用できない場合、ClickHouseはすべての結合が完了した後にフィルタを適用します。 @@ -604,7 +604,776 @@ USING (equi_column1, ... equi_columnN, asof_column) たとえば、次の表を考えてみます: -’テキスト -テーブル1テーブル2 + table_1 table_2 + event | ev_time | user_id event | ev_time | user_id + ----------|---------|---------- ----------|---------|---------- + ... ... + event_1_1 | 12:00 | 42 event_2_1 | 11:59 | 42 + ... event_2_2 | 12:30 | 42 + event_1_2 | 13:00 | 42 event_2_3 | 13:00 | 42 + ... ... -イベント/ev\_time\|user\_idイベント/ev\_time\|user\_id +`ASOF JOIN` ユーザイベントのタイムスタンプを `table_1` そして、イベントを見つける `table_2` タイムスタンプは、イベントのタイムスタンプに最も近い `table_1` 最も近い一致条件に対応します。 等しいタイムスタンプ値に最も近いします。 ここでは、 `user_id` 列は、等価上の結合に使用することができ、 `ev_time` 列は、最も近いマッチでの結合に使用できます。 この例では, `event_1_1` と結合することができます `event_2_1` と `event_1_2` と結合することができます `event_2_3`、しかし `event_2_2` 参加できない + +!!! note "メモ" + `ASOF` 結合は **ない** で支えられる [参加](../../engines/table-engines/special/join.md) テーブルエンジン。 + +既定の厳密さの値を設定するには、session構成パラメーターを使用します [join\_default\_strictness](../../operations/settings/settings.md#settings-join_default_strictness). + +#### GLOBAL JOIN {#global-join} + +通常を使用する場合 `JOIN` クエリはリモートサーバーに送信されます。 サブクエリは、右側のテーブルを作成するためにそれぞれに対して実行され、このテーブルで結合が実行されます。 言い換えれば、右のテーブルは各サーバー上に別々に形成される。 + +使用する場合 `GLOBAL ... JOIN` 最初に、リクエスター-サーバーがサブクエリーを実行して右のテーブルを計算します。 この一時テーブルは各リモートサーバーに渡され、送信された一時データを使用してクエリが実行されます。 + +を使用する場合は注意 `GLOBAL`. 詳細については、以下を参照してください [分散サブクエリ](#select-distributed-subqueries). + +#### 使用の推奨事項 {#usage-recommendations} + +実行しているとき `JOIN`、クエリの他の段階に関連して実行順序の最適化はありません。 結合(右側のテーブルでの検索)は、フィルター処理を行う前に実行されます。 `WHERE` そして、集約の前に。 処理順序を明示的に設定するには、以下を実行することを推奨します。 `JOIN` サブクエリを使用したサブクエリ。 + +例えば: + +``` sql +SELECT + CounterID, + hits, + visits +FROM +( + SELECT + CounterID, + count() AS hits + FROM test.hits + GROUP BY CounterID +) ANY LEFT JOIN +( + SELECT + CounterID, + sum(Sign) AS visits + FROM test.visits + GROUP BY CounterID +) USING CounterID +ORDER BY hits DESC +LIMIT 10 +``` + +``` text +┌─CounterID─┬───hits─┬─visits─┐ +│ 1143050 │ 523264 │ 13665 │ +│ 731962 │ 475698 │ 102716 │ +│ 722545 │ 337212 │ 108187 │ +│ 722889 │ 252197 │ 10547 │ +│ 2237260 │ 196036 │ 9522 │ +│ 23057320 │ 147211 │ 7689 │ +│ 722818 │ 90109 │ 17847 │ +│ 48221 │ 85379 │ 4652 │ +│ 19762435 │ 77807 │ 7026 │ +│ 722884 │ 77492 │ 11056 │ +└───────────┴────────┴────────┘ +``` + +サブクエリでは、特定のサブクエリの列を参照するために名前を設定したり、名前を使用したりすることはできません。 +で指定された列 `USING` 両方のサブクエリで同じ名前を持つ必要があり、他の列の名前は異なる必要があります。 別名を使用して、サブクエリの列の名前を変更できます(この例では、別名を使用します `hits` と `visits`). + +その `USING` 句は、これらの列の等価性を確立し、結合する一つ以上の列を指定します。 列のリストは、角かっこなしで設定されます。 より複雑な結合条件はサポートされていません。 + +右側のテーブル(サブクエリ結果)はRAMに存在します。 十分なメモリがない場合は、実行することはできません `JOIN`. + +クエリが同じで実行されるたびに `JOIN` 結果がキャッシュされていないため、サブクエリが再度実行されます。 これを回避するには、特別な [参加](../../engines/table-engines/special/join.md) テーブルエンジンは、常にRAMにある結合の準備された配列です。 + +場合によっては、使用する方が効率的です `IN` 代わりに `JOIN`. +様々なタイプの中で `JOIN` は、最も効率的です `ANY LEFT JOIN`、その後 `ANY INNER JOIN`. の少なくとも効率の高いて `ALL LEFT JOIN` と `ALL INNER JOIN`. + +必要な場合は `JOIN` ディメンションテーブ `JOIN` 右のテーブルがすべてのクエリに対して再アクセスされるため、あまり便利ではないかもしれません。 そのような場合には、 “external dictionaries” 代わりに使用する必要がある機能 `JOIN`. 詳細については、以下を参照してください [外部辞書](../dictionaries/external-dictionaries/external-dicts.md). + +**メモリの制限** + +クリックハウスは [ハッシュ結合](https://en.wikipedia.org/wiki/Hash_join) アルゴリズムだ クリックハウスは、 `` RAMにハッシュテーブルを作成します。 Join操作のメモリ消費を制限する必要がある場合は、次の設定を使用します: + +- [max\_rows\_in\_join](../../operations/settings/query-complexity.md#settings-max_rows_in_join) — Limits number of rows in the hash table. +- [max\_bytes\_in\_join](../../operations/settings/query-complexity.md#settings-max_bytes_in_join) — Limits size of the hash table. + +これらの制限のいずれかに達すると、ClickHouseは次のように機能します [join\_overflow\_mode](../../operations/settings/query-complexity.md#settings-join_overflow_mode) 設定を指示します。 + +#### 空またはNULLのセルの処理 {#processing-of-empty-or-null-cells} + +を結合を使ったテーブルの結合、空の細胞が表示される場合があります。 を設定 [join\_use\_nulls](../../operations/settings/settings.md#join_use_nulls) する方法を定義するClickHouse填するこれらの細胞。 + +この `JOIN` キーは [Nullable](../data-types/nullable.md) フィールド、キーの少なくとも一方が値を持つ行 [NULL](../syntax.md#null-literal) 結合されていません。 + +#### 構文の制限 {#syntax-limitations} + +倍数のため `JOIN` 単一の句 `SELECT` クエリ: + +- すべての列を `*` サブクエリではなく、テーブルが結合されている場合にのみ使用可能です。 +- その `PREWHERE` 句は使用できません。 + +のために `ON`, `WHERE`、と `GROUP BY` 句: + +- 任意の式を使用することはできません `ON`, `WHERE`、と `GROUP BY` ただし、aに式を定義することはできます `SELECT` これらの節では、エイリアスを使用して句を使用します。 + +### WHERE句 {#select-where} + +WHERE句がある場合は、UInt8型の式が含まれている必要があります。 これは通常、比較演算子と論理演算子を含む式です。 +この表現を使用するフィルタリングデータはすべての小さなものに過ぎません。 + +ば土地の再評価を行い、土地再評価支援データベースのテーブルエンジンの式が値評価され、使用が可能。 + +### PREWHERE句 {#prewhere-clause} + +この句はWHERE句と同じ意味を持ちます。 違いは、テーブルからデータを読み取ることです。 +PRELOWを使用する場合は、まずPRELOWを実行するために必要な列のみが読み込まれます。 次に、クエリを実行するために必要な他の列が読み込まれますが、PREWHERE式がtrueの場合のブロックのみが読み込まれます。 + +クエリの少数の列で使用されるが、強力なデータのフィルタリングを提供するろ過条件がある場合は、PREWHEREを使用することは理にかなっています。 これにより、読み取るデータの量が減少します。 + +たとえば、多数の列を抽出するが、少数の列のフィルタリングしか持たないクエリに対してPREWHEREを記述すると便利です。 + +PREWHEREのようテーブルからの `*MergeTree` 家族 + +クエリは同時にPREWHEREとWHEREを指定できます。 この場合、PREWHEREはWHEREに先行します。 + +この ‘optimize\_move\_to\_prewhere’ 設定は1に設定され、PREWHEREは省略され、システムはヒューリスティックを使用して式の一部をどこからPREWHEREに自動的に移動します。 + +### GROUP BY句 {#select-group-by-clause} + +これは、列指向DBMSの最も重要な部分の一つです。 + +GROUP BY句がある場合は、式のリストが含まれている必要があります。 それぞれの式は、ここではaと呼ばれます。 “key”. +SELECT句、HAVING句、ORDER BY句のすべての式は、キーまたは集計関数から計算する必要があります。 つまり、テーブルから選択された各列は、キーまたは集計関数内で使用する必要があります。 + +クエリに集計関数内のテーブル列のみが含まれている場合、GROUP BY句を省略することができ、空のキーのセットによる集計が想定されます。 + +例えば: + +``` sql +SELECT + count(), + median(FetchTiming > 60 ? 60 : FetchTiming), + count() - sum(Refresh) +FROM hits +``` + +ただし、標準SQLとは対照的に、テーブルに行がない場合(まったくない場合、またはwhereフィルタを使用した後に行がない場合)、空の結果が返され、集計関数 + +MySQL(および標準SQLに準拠)とは対照的に、キーまたは集約関数(定数式を除く)にないカラムの値を取得することはできません。 これを回避するには、次のコマンドを使用します ‘any’ 集約関数(最初に遭遇した値を取得する)または ‘min/max’. + +例えば: + +``` sql +SELECT + domainWithoutWWW(URL) AS domain, + count(), + any(Title) AS title -- getting the first occurred page header for each domain. +FROM hits +GROUP BY domain +``` + +異なるキー値が検出されるたびに、GROUP BYは集計関数値のセットを計算します。 + +GROUP BYは、配列列ではサポートされません。 + +集計関数の引数として定数を指定することはできません。 例:sum(1)。 これの代わりに、定数を取り除くことができます。 例えば: `count()`. + +#### ヌル処理 {#null-processing} + +グループ化のために、ClickHouseは [NULL](../syntax.md) 値として、 `NULL=NULL`. + +これが何を意味するのかを示す例があります。 + +このテーブルがあるとします: + +``` text +┌─x─┬────y─┐ +│ 1 │ 2 │ +│ 2 │ ᴺᵁᴸᴸ │ +│ 3 │ 2 │ +│ 3 │ 3 │ +│ 3 │ ᴺᵁᴸᴸ │ +└───┴──────┘ +``` + +クエリ `SELECT sum(x), y FROM t_null_big GROUP BY y` 結果は: + +``` text +┌─sum(x)─┬────y─┐ +│ 4 │ 2 │ +│ 3 │ 3 │ +│ 5 │ ᴺᵁᴸᴸ │ +└────────┴──────┘ +``` + +あなたが見ることが `GROUP BY` のために `y = NULL` 総括 `x`、かのように `NULL` この値です。 + +いくつかのキーを渡す場合 `GROUP BY`、結果はあなたの選択のすべての組み合わせを与えるかのように `NULL` 特定の値でした。 + +#### 合計モディファイア {#with-totals-modifier} + +WITH TOTALS修飾子を指定すると、別の行が計算されます。 この行には、デフォルト値(ゼロまたは空行)を含むキー列と、すべての行にわたって計算された値を持つ集計関数の列があります “total” 値)。 + +この余分な行は、他の行とは別に、JSON\*、TabSeparated\*、およびPretty\*形式で出力されます。 他の形式では、この行は出力されません。 + +JSON\*形式では、この行は別の行として出力されます ‘totals’ フィールド。 TabSeparated\*形式では、行はメインの結果の後に来て、空の行(他のデータの後)が先行します。 Pretty\*形式では、行は主な結果の後に別のテーブルとして出力されます。 + +`WITH TOTALS` HAVINGが存在する場合は、さまざまな方法で実行できます。 この動作は、 ‘totals\_mode’ 設定。 +デフォルトでは, `totals_mode = 'before_having'`. この場合, ‘totals’ HAVINGおよびHAVINGを通過しない行を含む、すべての行にわたって計算されます ‘max\_rows\_to\_group\_by’. + +他の選択肢には、inを持つ行を通過する行のみが含まれます ‘totals’、および設定とは異なる動作をします `max_rows_to_group_by` と `group_by_overflow_mode = 'any'`. + +`after_having_exclusive` – Don't include rows that didn't pass through `max_rows_to_group_by`. つまり, ‘totals’ 以下の行と同じ数の行を持つことになります。 `max_rows_to_group_by` 省略した。 + +`after_having_inclusive` – Include all the rows that didn't pass through ‘max\_rows\_to\_group\_by’ で ‘totals’. つまり, ‘totals’ これは、次の場合と同じか、同じ数の行を持つことになります `max_rows_to_group_by` 省略した。 + +`after_having_auto` – Count the number of rows that passed through HAVING. If it is more than a certain amount (by default, 50%), include all the rows that didn't pass through ‘max\_rows\_to\_group\_by’ で ‘totals’. それ以外の場合は、含めないでください。 + +`totals_auto_threshold` – By default, 0.5. The coefficient for `after_having_auto`. + +もし `max_rows_to_group_by` と `group_by_overflow_mode = 'any'` 使用されない、すべての変化の `after_having` 同じであり、それらのいずれかを使用することができます(たとえば, `after_having_auto`). + +JOIN句の副照会を含む副照会の合計を使用することができます(この場合、それぞれの合計値が結合されます)。 + +#### 外部メモリによるグループ化 {#select-group-by-in-external-memory} + +一時データのディスクへのダンプを有効にして、使用中のメモリ使用量を制限できます `GROUP BY`. +その [max\_bytes\_before\_external\_group\_by](../../operations/settings/settings.md#settings-max_bytes_before_external_group_by) 設定のしきい値RAM消費のためにダンピング `GROUP BY` ファイルシステムへの一時データ。 0(デフォルト)に設定すると、無効になります。 + +使用する場合 `max_bytes_before_external_group_by`、私達は置くことを推薦します `max_memory_usage` 約二倍の高さ。 日付の読み取りと中間データの生成(1)と中間データのマージ(2)です。 ダンピングデータのファイルシステムでのみ発生時のステージ1です。 一時データがダンプされなかった場合、ステージ2はステージ1と同じ量のメモリを必要とする可能性があります。 + +たとえば、次の場合 [max\_memory\_usage](../../operations/settings/settings.md#settings_max_memory_usage) 10000000000に設定されていて、外部集約を使用したい場合は、次のように設定するのが理にかなっています `max_bytes_before_external_group_by` to10000000000,そしてmax\_memory\_usageへ2000000000. 外部集約がトリガーされると(一時データのダンプが少なくともひとつある場合)、RAMの最大消費量はわずかに多くなります `max_bytes_before_external_group_by`. + +分散クエリ処理では、リモートサーバーで外部集約が実行されます。 リクエスタサーバが少量のRAMしか使用しないようにするには、以下を設定します `distributed_aggregation_memory_efficient` へ1. + +データをディスクにマージするとき、およびリモートサーバーからの結果をマージするとき `distributed_aggregation_memory_efficient` 設定が有効になっている、消費まで `1/256 * the_number_of_threads` RAMの総量から。 + +外部集約が有効になっているときに、 `max_bytes_before_external_group_by` of data (i.e. data was not flushed), the query runs just as fast as without external aggregation. If any temporary data was flushed, the run time will be several times longer (approximately three times). + +あなたが持っている場合 `ORDER BY` と `LIMIT` 後に `GROUP BY` のデータ量に依存します。 `LIMIT`、ないテーブル全体で。 しかし、もし `ORDER BY` 持っていない `LIMIT` を忘れてはならないよ外部ソート (`max_bytes_before_external_sort`). + +### 句による制限 {#limit-by-clause} + +とのクエリ `LIMIT n BY expressions` 句は最初の句を選択します。 `n` それぞれの個別の値の行 `expressions`. をキー用 `LIMIT BY` 任意の数を含むことができます [式](../syntax.md#syntax-expressions). + +ClickHouseは次の構文をサポートします: + +- `LIMIT [offset_value, ]n BY expressions` +- `LIMIT n OFFSET offset_value BY expressions` + +中のクエリ処理、ClickHouseを選択しデータの順に並べ替えることによります。 ソート-キーは、明示的に [ORDER BY](#select-order-by) 句または暗黙的にテーブルエンジンのプロパティとして。 次にClickHouseが適用されます `LIMIT n BY expressions` 最初のものを返します `n` それぞれの個別の組み合わせの行 `expressions`. もし `OFFSET` 指定され、各データブロックに所属する異なる組み合わせ `expressions`、ClickHouseスキップ `offset_value` ブロックの先頭からの行の数との最大値を返します。 `n` 結果としての行。 もし `offset_value` データブロック内の行数より大きい場合、ClickHouseはブロックからゼロ行を返します。 + +`LIMIT BY` に関連していない `LIMIT`. これらは両方とも同じクエリで使用できます。 + +**例** + +サンプル表: + +``` sql +CREATE TABLE limit_by(id Int, val Int) ENGINE = Memory; +INSERT INTO limit_by values(1, 10), (1, 11), (1, 12), (2, 20), (2, 21); +``` + +クエリ: + +``` sql +SELECT * FROM limit_by ORDER BY id, val LIMIT 2 BY id +``` + +``` text +┌─id─┬─val─┐ +│ 1 │ 10 │ +│ 1 │ 11 │ +│ 2 │ 20 │ +│ 2 │ 21 │ +└────┴─────┘ +``` + +``` sql +SELECT * FROM limit_by ORDER BY id, val LIMIT 1, 2 BY id +``` + +``` text +┌─id─┬─val─┐ +│ 1 │ 11 │ +│ 1 │ 12 │ +│ 2 │ 21 │ +└────┴─────┘ +``` + +その `SELECT * FROM limit_by ORDER BY id, val LIMIT 2 OFFSET 1 BY id` queryは同じ結果を返します。 + +次のクエリは、それぞれの上位5個のリファラーを返します `domain, device_type` 合計で最大100行のペア (`LIMIT n BY + LIMIT`). + +``` sql +SELECT + domainWithoutWWW(URL) AS domain, + domainWithoutWWW(REFERRER_URL) AS referrer, + device_type, + count() cnt +FROM hits +GROUP BY domain, referrer, device_type +ORDER BY cnt DESC +LIMIT 5 BY domain, device_type +LIMIT 100 +``` + +### HAVING Clause {#having-clause} + +WHERE句と同様に、GROUP BYの後に受け取った結果をフィルタリングできます。 +集約前に実行される箇所と異なる箇所(GROUP BY)を有している間は、その後に実行される。 +集計が実行されない場合、HAVINGは使用できません。 + +### ORDER BY句 {#select-order-by} + +ORDER BY句には式のリストが含まれており、それぞれにDESCまたはASC(ソート方向)を割り当てることができます。 方向が指定されていない場合は、ASCが想定されます。 ASCは昇順でソートされ、DESCは降順でソートされます。 並べ替え方向は、リスト全体ではなく、単一の式に適用されます。 例えば: `ORDER BY Visits DESC, SearchPhrase` + +文字列値による並べ替えでは、照合(比較)を指定できます。 例えば: `ORDER BY SearchPhrase COLLATE 'tr'` -によるソートキーワードの昇順では、トルコのアルファベット大文字、小文字大文字と小文字を区別しません、ここから文字列はUTF-8エンコードされます。 COLLATEは、各式に対して独立して順番に指定するかどうかを指定できます。 ASCまたはDESCが指定されている場合は、その後にCOLLATEが指定されます。 COLLATEを使用する場合、並べ替えは常に大文字と小文字を区別しません。 + +COLLATEでソートするのは、通常のバイトでのソートよりも効率的ではないため、少数の行の最終ソートにはCOLLATEを使用することをお勧めします。 + +並べ替え式のリストに同じ値を持つ行は、任意の順序で出力されます。 +ORDER BY句を省略すると、行の順序も未定義になり、非決定的になることもあります。 + +`NaN` と `NULL` ソート順序: + +- モディファイア `NULLS FIRST` — First `NULL`、その後 `NaN`、その後、他の値。 +- モディファイア `NULLS LAST` — First the values, then `NaN`、その後 `NULL`. +- Default — The same as with the `NULLS LAST` 修飾子。 + +例えば: + +テーブルのため + +``` text +┌─x─┬────y─┐ +│ 1 │ ᴺᵁᴸᴸ │ +│ 2 │ 2 │ +│ 1 │ nan │ +│ 2 │ 2 │ +│ 3 │ 4 │ +│ 5 │ 6 │ +│ 6 │ nan │ +│ 7 │ ᴺᵁᴸᴸ │ +│ 6 │ 7 │ +│ 8 │ 9 │ +└───┴──────┘ +``` + +クエリの実行 `SELECT * FROM t_null_nan ORDER BY y NULLS FIRST` を取得するには: + +``` text +┌─x─┬────y─┐ +│ 1 │ ᴺᵁᴸᴸ │ +│ 7 │ ᴺᵁᴸᴸ │ +│ 1 │ nan │ +│ 6 │ nan │ +│ 2 │ 2 │ +│ 2 │ 2 │ +│ 3 │ 4 │ +│ 5 │ 6 │ +│ 6 │ 7 │ +│ 8 │ 9 │ +└───┴──────┘ +``` + +浮動小数点数がソートされると、Nanは他の値とは別になります。 ソート順序にかかわらず、Nanは最後に来ます。 言い換えれば、昇順ソートの場合、それらは他のすべての数字よりも大きいかのように配置され、降順ソートの場合は残りの数字よりも小さいかのよう + +ORDER BYに加えて十分に小さい制限が指定されている場合は、より少ないRAMが使用されます。 それ以外の場合、消費されるメモリの量は、ソートのためのデータ量に比例します。 分散クエリ処理では、GROUP BYを省略した場合、リモートサーバー上で部分的にソートが行われ、結果はリクエスタサーバー上でマージされます。 これは、分散ソートの場合、ソートするデータの量は、単一のサーバー上のメモリ量よりも大きくなる可能性があることを意味します。 + +十分なRAMがない場合は、(ディスク上の一時ファイルを作成する)外部メモリにソートを実行することが可能です。 設定を使用する `max_bytes_before_external_sort` この目的のために。 0(デフォルト)に設定すると、外部ソートは無効になります。 これを有効にすると、ソートするデータのボリュームが指定されたバイト数に達すると、収集されたデータがソートされ、一時ファイルにダンプされます。 すべてのデータの読み込み、すべてのソートファイルとして合併し、その結果を出力します。 ファイルはconfigの/var/lib/clickhouse/tmp/ディレクトリに書き込まれます(デフォルトでは、 ‘tmp\_path’ この設定を変更するパラメータ)。 + +クエリを実行すると ‘max\_bytes\_before\_external\_sort’. このため、この設定の値は、以下よりも大幅に小さくする必要があります ‘max\_memory\_usage’. たとえば、サーバーに128GBのRAMがあり、単一のクエリを実行する必要がある場合は、次のように設定します ‘max\_memory\_usage’ 100GBに、 ‘max\_bytes\_before\_external\_sort’ 80GBまで。 + +外部ソートは、RAMのソートよりも効果的ではありません。 + +### SELECT句 {#select-select} + +[式](../syntax.md#syntax-expressions) で指定される `SELECT` 句は、上記の句のすべての操作が終了した後に計算されます。 これらの式は、結果の別々の行に適用されるかのように機能します。 式の場合 `SELECT` 句には集計関数が含まれ、ClickHouseは集計関数とその引数として使用される式を処理します。 [GROUP BY](#select-group-by-clause) 集約。 + +結果にすべての列を含める場合は、アスタリスクを使用します (`*`)シンボル。 例えば, `SELECT * FROM ...`. + +結果のいくつかの列をaと一致させるには [re2unit description in lists](https://en.wikipedia.org/wiki/RE2_(software)) 正規表現を使用することができます `COLUMNS` 式。 + +``` sql +COLUMNS('regexp') +``` + +たとえば、次の表を考えてみます: + +``` sql +CREATE TABLE default.col_names (aa Int8, ab Int8, bc Int8) ENGINE = TinyLog +``` + +以下のクエリを選択しデータからすべての列を含む `a` 彼らの名前のシンボル。 + +``` sql +SELECT COLUMNS('a') FROM col_names +``` + +``` text +┌─aa─┬─ab─┐ +│ 1 │ 1 │ +└────┴────┘ +``` + +選択した列は、アルファベット順ではなく返されます。 + +複数を使用できます `COLUMNS` クエリ内の式とそれらに関数を適用します。 + +例えば: + +``` sql +SELECT COLUMNS('a'), COLUMNS('c'), toTypeName(COLUMNS('c')) FROM col_names +``` + +``` text +┌─aa─┬─ab─┬─bc─┬─toTypeName(bc)─┐ +│ 1 │ 1 │ 1 │ Int8 │ +└────┴────┴────┴────────────────┘ +``` + +によって返される各列 `COLUMNS` 式は、別の引数として関数に渡されます。 また、他の引数を関数に渡すこともできます。 関数を使用する場合は注意してください。 関数が渡された引数の数をサポートしていない場合、ClickHouseは例外をスローします。 + +例えば: + +``` sql +SELECT COLUMNS('a') + COLUMNS('c') FROM col_names +``` + +``` text +Received exception from server (version 19.14.1): +Code: 42. DB::Exception: Received from localhost:9000. DB::Exception: Number of arguments for function plus doesn't match: passed 3, should be 2. +``` + +この例では, `COLUMNS('a')` 二つの列を返します: `aa` と `ab`. `COLUMNS('c')` を返します `bc` コラム その `+` 演算子は3つの引数には適用できないため、ClickHouseは関連するメッセージで例外をスローします。 + +一致した列 `COLUMNS` 式のデータ型は異なる場合があります。 もし `COLUMNS` 列には一致せず、唯一の式です `SELECT`、ClickHouseは例外をスローします。 + +### DISTINCT句 {#select-distinct} + +DISTINCTが指定されている場合、結果に完全に一致する行のすべてのセットから単一の行だけが残ります。 +結果は、group BYが集計関数なしでSELECTで指定されたすべてのフィールドに指定された場合と同じになります。 しかし、GROUP BYとの違いはいくつかあります: + +- DISTINCTはGROUP BYと一緒に適用できます。 +- ORDER BYを省略してLIMITを定義すると、必要な数の異なる行が読み込まれた直後にクエリが実行を停止します。 +- データブロックは、クエリ全体の実行が完了するのを待たずに、処理されたときに出力されます。 + +個別には対応していない場合に選択して少なくとも一つの配列です。 + +`DISTINCT` で動作 [NULL](../syntax.md) まるで `NULL` 特定の値であり、 `NULL=NULL`. つまり、 `DISTINCT` 結果、異なる組み合わせ `NULL` 一度だけ発生する。 + +ClickHouseは使用を支えます `DISTINCT` と `ORDER BY` あるクエリ内の異なる列の句。 その `DISTINCT` の前に句が実行されます。 `ORDER BY` 句。 + +表の例: + +``` text +┌─a─┬─b─┐ +│ 2 │ 1 │ +│ 1 │ 2 │ +│ 3 │ 3 │ +│ 2 │ 4 │ +└───┴───┘ +``` + +とデータを選択すると `SELECT DISTINCT a FROM t1 ORDER BY b ASC` クエリは、我々は次の結果を得る: + +``` text +┌─a─┐ +│ 2 │ +│ 1 │ +│ 3 │ +└───┘ +``` + +ソートの方向を変えれば `SELECT DISTINCT a FROM t1 ORDER BY b DESC`、我々は、次の結果を得る: + +``` text +┌─a─┐ +│ 3 │ +│ 1 │ +│ 2 │ +└───┘ +``` + +行 `2, 4` ソート前にカットされた。 + +この実装に特異性を考慮グます。 + +### LIMIT句 {#limit-clause} + +`LIMIT m` 最初のものを選択することができます `m` 結果からの行。 + +`LIMIT n, m` 最初のものを選択することができます `m` 最初の行をスキップした後の結果の行 `n` 行。 その `LIMIT m OFFSET n` 構文もサポートされています。 + +`n` と `m` 負でない整数でなければなりません。 + +がない場合 `ORDER BY` 結果を明示的にソートする句は、結果が任意で非決定的である可能性があります。 + +### UNION ALL句 {#union-all-clause} + +UNION ALLを使用すると、任意の数のクエリを結合できます。 例えば: + +``` sql +SELECT CounterID, 1 AS table, toInt64(count()) AS c + FROM test.hits + GROUP BY CounterID + +UNION ALL + +SELECT CounterID, 2 AS table, sum(Sign) AS c + FROM test.visits + GROUP BY CounterID + HAVING c > 0 +``` + +UNION ALLのみがサポートされます。 通常の共用体(UNION DISTINCT)はサポートされていません。 UNION DISTINCTが必要な場合は、UNION ALLを含むサブクエリからSELECT DISTINCTを書くことができます。 + +UNION ALLの一部であるクエリを同時に実行し、その結果を混在させることができます。 + +結果の構造(列の数と型)は、クエリに一致する必要があります。 しかし、列名は異なる場合があります。 この場合、最終的な結果の列名は最初のクエリから取得されます。 タイプ鋳造は連合のために行われます。 たとえば、結合されている二つのクエリが非同じフィールドを持つ場合-`Nullable` と `Nullable` 互換性のあるタイプのタイプ `UNION ALL` は `Nullable` タイプフィールド。 + +UNION ALLの一部であるクエリは、角かっこで囲むことはできません。 ORDER BYとLIMITは、最終結果ではなく、別々のクエリに適用されます。 最終結果に変換を適用する必要がある場合は、FROM句のサブクエリにUNION ALLを含むすべてのクエリを入れることができます。 + +### INTO OUTFILE句 {#into-outfile-clause} + +を追加 `INTO OUTFILE filename` 指定されたファイルにクエリ出力をリダイレクトする句(filenameは文字列リテラル)。 +MySQLとは対照的に、ファイルはクライアント側で作成されます。 同じファイル名のファイルが既に存在する場合、クエリは失敗します。 +この機能は、コマンドラインクライアントとclickhouse-localで使用できます(HTTPインターフェイス経由で送信されるクエリは失敗します)。 + +デフォルトの出力形式はTabSeparatedです(コマンドラインクライアントバッチモードと同じです)。 + +### フォーマット句 {#format-clause} + +指定 ‘FORMAT format’ 指定された形式のデータを取得する。 +これは、便宜上、またはダンプを作成するために使用できます。 +詳細については、以下を参照してください “Formats”. +これは、DBへのアクセスに使用される設定とインターフェイスの両方に依存します。 HTTPインターフェイスとバッチモードのコマンドラインクライアントの場合、デフォルトの形式はTabSeparatedです。 対話モードのコマンドラインクライアントの場合、デフォルトの形式はPrettyCompactです(魅力的でコンパクトな表があります)。 + +コマンドラインクライアントを使用する場合、データは内部の効率的な形式でクライアントに渡されます。 クライアントは、クエリのFORMAT句を独立して解釈し、データ自体をフォーマットします(したがって、ネットワークとサーバーを負荷から解放します)。 + +### 演算子の場合 {#select-in-operators} + +その `IN`, `NOT IN`, `GLOBAL IN`、と `GLOBAL NOT IN` 事業者は、別途その機能はかなり豊富です。 + +演算子の左側は、単一の列またはタプルです。 + +例: + +``` sql +SELECT UserID IN (123, 456) FROM ... +SELECT (CounterID, UserID) IN ((34, 123), (101500, 456)) FROM ... +``` + +左側がインデックス内の単一の列で、右側が定数のセットである場合、システムはクエリを処理するためにインデックスを使用します。 + +Don't list too many values explicitly (i.e. millions). If a data set is large, put it in a temporary table (for example, see the section “External data for query processing”)、サブクエリを使用します。 + +演算子の右側には、定数式のセット、定数式を持つタプルのセット(上の例で示します)、データベーステーブルの名前、または括弧で囲んだサブクエリのセッ + +演算子の右側がテーブルの名前である場合(たとえば, `UserID IN users`)これはサブクエリと同じです `UserID IN (SELECT * FROM users)`. これは、クエリと共に送信される外部データを操作する場合に使用します。 たとえば、クエリは、ロードされたユーザIdのセットと一緒に送信することができます。 ‘users’ フィルタリングする必要がある一時テーブル。 + +演算子の右側が、Setエンジン(常にRAMにある準備済みデータ-セット)を持つテーブル名である場合、データ-セットはクエリごとに再作成されません。 + +サブクエリでは、タプルのフィルター処理に複数の列を指定できます。 +例えば: + +``` sql +SELECT (CounterID, UserID) IN (SELECT CounterID, UserID FROM ...) FROM ... +``` + +IN演算子の左と右の列は同じ型にする必要があります。 + +IN演算子およびサブクエリは、集計関数およびラムダ関数を含む、クエリの任意の部分で発生する可能性があります。 +例えば: + +``` sql +SELECT + EventDate, + avg(UserID IN + ( + SELECT UserID + FROM test.hits + WHERE EventDate = toDate('2014-03-17') + )) AS ratio +FROM test.hits +GROUP BY EventDate +ORDER BY EventDate ASC +``` + +``` text +┌──EventDate─┬────ratio─┐ +│ 2014-03-17 │ 1 │ +│ 2014-03-18 │ 0.807696 │ +│ 2014-03-19 │ 0.755406 │ +│ 2014-03-20 │ 0.723218 │ +│ 2014-03-21 │ 0.697021 │ +│ 2014-03-22 │ 0.647851 │ +│ 2014-03-23 │ 0.648416 │ +└────────────┴──────────┘ +``` + +月17th後の各日のために,月17日にサイトを訪問したユーザーによって行われたページビューの割合を数えます. +IN句のサブクエリは、常に単一のサーバーで一度だけ実行されます。 従属サブクエリはありません。 + +#### ヌル処理 {#null-processing-1} + +要求の処理中にIN演算子は、次の条件を満たす操作の結果 [NULL](../syntax.md) は常に等しい `0` かどうかにかかわらず `NULL` 演算子の右側または左側にあります。 `NULL` 値はどのデータセットにも含まれず、互いに対応せず、比較することもできません。 + +ここに例があります `t_null` テーブル: + +``` text +┌─x─┬────y─┐ +│ 1 │ ᴺᵁᴸᴸ │ +│ 2 │ 3 │ +└───┴──────┘ +``` + +クエリの実行 `SELECT x FROM t_null WHERE y IN (NULL,3)` あなたに次の結果を与えます: + +``` text +┌─x─┐ +│ 2 │ +└───┘ +``` + +あなたはその行を見ることができます `y = NULL` は、クエリの結果からスローされます。 これは、ClickHouseが `NULL` に含まれている `(NULL,3)` セット、戻り値 `0` 操作の結果として、 `SELECT` この行を最終出力から除外します。 + +``` sql +SELECT y IN (NULL, 3) +FROM t_null +``` + +``` text +┌─in(y, tuple(NULL, 3))─┐ +│ 0 │ +│ 1 │ +└───────────────────────┘ +``` + +#### 分散サブクエリ {#select-distributed-subqueries} + +サブクエリを持つIN-sには二つのオプションがあります。 `IN` / `JOIN` と `GLOBAL IN` / `GLOBAL JOIN`. これらは、分散クエリ処理の実行方法が異なります。 + +!!! attention "注意" + 以下で説明するアル [設定](../../operations/settings/settings.md) `distributed_product_mode` 設定。 + +通常のINを使用すると、クエリはリモートサーバーに送信され、それぞれのサブクエリが実行されます。 `IN` または `JOIN` 句。 + +使用する場合 `GLOBAL IN` / `GLOBAL JOINs`、最初にすべての副照会はのために動きます `GLOBAL IN` / `GLOBAL JOINs` 結果は一時テーブルに収集されます。 次に、各リモートサーバーに一時テーブルが送信され、この一時データを使用してクエリが実行されます。 + +非分散クエリの場合は、regularを使用します `IN` / `JOIN`. + +サブクエリを使用するときは注意してください。 `IN` / `JOIN` 分散クエリ処理のための句。 + +いくつかの例を見てみましょう。 クラスター内の各サーバーが正常 **local\_table**. 各サーバーには、 **distributed\_table** とテーブル **分散** これは、クラスタ内のすべてのサーバーを参照します。 + +クエリの場合 **distributed\_table** クエリはすべてのリモートサーバーに送信され、それらのサーバー上で実行されます。 **local\_table**. + +たとえば、クエリ + +``` sql +SELECT uniq(UserID) FROM distributed_table +``` + +すべてのリモートサーバーに送信されます。 + +``` sql +SELECT uniq(UserID) FROM local_table +``` + +そして、中間結果を組み合わせることができる段階に達するまで、それぞれを並行して実行します。 その後、中間結果が要求元サーバーに返され、その上にマージされ、最終的な結果がクライアントに送信されます。 + +次にINを使用してクエリを調べてみましょう: + +``` sql +SELECT uniq(UserID) FROM distributed_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM local_table WHERE CounterID = 34) +``` + +- 二つのサイトの観客の交差点の計算。 + +このクエリを送信すべてのリモートサーバーとして + +``` sql +SELECT uniq(UserID) FROM local_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM local_table WHERE CounterID = 34) +``` + +つまり、IN句のデータ-セットは、各サーバー上で独立して収集され、各サーバー上にローカルに格納されるデータ全体でのみ収集されます。 + +これは、このケースに備えられており、単一のユーザー Idのデータが単一のサーバー上に完全に存在するように、クラスタサーバーにデータを分散している場合に、正し この場合、必要なデータはすべて各サーバーでローカルに利用できます。 それ以外の場合、結果は不正確になります。 私たちは,シミュレーションをクエリとして “local IN”. + +正方のクエリにしているときのデータはランダムにクラスタサーバを指定でき **distributed\_table** サブクエリ内。 クエリは次のようになります: + +``` sql +SELECT uniq(UserID) FROM distributed_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM distributed_table WHERE CounterID = 34) +``` + +このクエリを送信すべてのリモートサーバーとして + +``` sql +SELECT uniq(UserID) FROM local_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM distributed_table WHERE CounterID = 34) +``` + +サブクエリは、各リモートサーバーで実行を開始します。 サブクエリは分散テーブルを使用するため、各リモートサーバー上にあるサブクエリは、すべてのリモートサーバーに再送信されます。 + +``` sql +SELECT UserID FROM local_table WHERE CounterID = 34 +``` + +たとえば、100台のサーバーのクラスターがある場合、クエリ全体を実行するには10,000個の基本要求が必要になります。 + +そのような場合は、常にIN代わりにGLOBAL INを使用する必要があります。 クエリでどのように動作するかを見てみましょう + +``` sql +SELECT uniq(UserID) FROM distributed_table WHERE CounterID = 101500 AND UserID GLOBAL IN (SELECT UserID FROM distributed_table WHERE CounterID = 34) +``` + +リクエスタサーバはサブクエリを実行します + +``` sql +SELECT UserID FROM distributed_table WHERE CounterID = 34 +``` + +結果はRAMの一時テーブルに入れられます。 次に、要求は各リモートサーバーに次のように送信されます + +``` sql +SELECT uniq(UserID) FROM local_table WHERE CounterID = 101500 AND UserID GLOBAL IN _data1 +``` + +そして、一時テーブル `_data1` クエリを使用してすべてのリモートサーバーに送信されます(一時テーブルの名前は実装定義です)。 + +これは、通常のINを使用するよりも最適です。 ただし、次の点に留意してください: + +1. 一時テーブルを作成する場合、データは一意になりません。 ネットワーク経由で送信されるデータの量を減らすには、サブクエリでDISTINCTを指定します。 (あなたは通常のためにこれを行う必要はありません。) +2. 一時テーブルは、すべてのリモートサーバーに送信されます。 送信はネットワークトポロジを考慮しません。 たとえば、リクエスタサーバに対して非常に離れたデータセンターに10台のリモートサーバーが存在する場合、データはチャネル経由でリモートデータセンターに10回送 をしないようにして大量のデータセット利用の場合グローバルです。 +3. 発信する場合にはデータへのリモートサーバー、ネットワークの帯域幅は設定できます。 ネッ +4. GLOBAL INを定期的に使用する必要がないように、サーバー間でデータを分散してみてください。 +5. グローバルを頻繁に使用する必要がある場合は、クエリを単一のデータセンター内で完全に処理できるように、レプリカの単一のグループが高速ネットワー + +また、ローカルテーブルを指定することも意味があります。 `GLOBAL IN` 条項の場合には、この地方のテーブルのみの文章、映像、音声サーバーに使用したいデータからですることができます。 + +### 極値 {#extreme-values} + +結果に加えて、結果列の最小値と最大値を取得することもできます。 これを行うには、 **極端な** 1に設定します。 数値型、日付、および時刻を含む日付について、最小値と最大値が計算されます。 その他の列では、既定値が出力されます。 + +An extra two rows are calculated – the minimums and maximums, respectively. These extra two rows are output in `JSON*`, `TabSeparated*`、と `Pretty*` [形式](../../interfaces/formats.md)、他の行とは別に。 他の形式では出力されません。 + +で `JSON*` フォーマットでは、極値は別の形式で出力されます。 ‘extremes’ フィールド。 で `TabSeparated*` 書式、行は主な結果の後に来る、と後 ‘totals’ 存在する場合。 これは、(他のデータの後に)空の行が先行しています。 で `Pretty*` この行は、メインの結果の後に別のテーブルとして出力されます。 `totals` 存在する場合。 + +極端な値は、前の行について計算されます `LIMIT`,しかし、後に `LIMIT BY`. ただし、使用する場合 `LIMIT offset, size`、前の行 `offset` に含まれています `extremes`. ストリーム要求では、結果には、通過した少数の行が含まれることもあります `LIMIT`. + +### 備考 {#notes} + +その `GROUP BY` と `ORDER BY` 句は定位置引数をサポートしません。 これはMySQLと矛盾しますが、標準SQLに準拠しています。 +例えば, `GROUP BY 1, 2` will be interpreted as grouping by constants (i.e. aggregation of all rows into one). + +同義語を使用できます (`AS` クエリの任意の部分でエイリアス)。 + +式の代わりに、クエリの任意の部分にアスタリスクを付けることができます。 クエリが分析されると、アスタリスクはすべてのテーブルの列のリストに展開されます。 `MATERIALIZED` と `ALIAS` 列)。 アスタリスクの使用が正当化されるケースはほんのわずかです: + +- テーブルダンプを作成するとき。 +- システムテーブルなど、少数の列だけを含むテーブルの場合。 +- テーブル内の列に関する情報を取得するためのものです。 この場合、 `LIMIT 1`. しかし、それを使用する方が良いです `DESC TABLE` クエリ。 +- 少数のコラムの強いろ過がを使用してある時 `PREWHERE`. +- サブクエリでは(外部クエリに必要のない列はサブクエリから除外されるため)。 + +他のすべてのケースでは、利点の代わりに柱状DBMSの欠点しか与えないので、アスタリスクを使用することはお勧めしません。 つまり、アスタリスクを使用することはお勧めしません。 + +[元の記事](https://clickhouse.tech/docs/en/query_language/select/) diff --git a/docs/redirects.txt b/docs/redirects.txt index df406d89eb3..13392e5dce5 100644 --- a/docs/redirects.txt +++ b/docs/redirects.txt @@ -160,6 +160,7 @@ interfaces/http_interface.md interfaces/http.md interfaces/third-party/client_libraries.md interfaces/third-party/client-libraries.md interfaces/third-party_client_libraries.md interfaces/third-party/client-libraries.md interfaces/third-party_gui.md interfaces/third-party/gui.md +interfaces/third_party/index.md interfaces/third-party/index.md introduction/distinctive_features.md introduction/distinctive-features.md introduction/features_considered_disadvantages.md introduction/distinctive-features.md introduction/possible_silly_questions.md faq/general.md diff --git a/docs/tools/translate/util.py b/docs/tools/translate/util.py new file mode 120000 index 00000000000..7f16d68497e --- /dev/null +++ b/docs/tools/translate/util.py @@ -0,0 +1 @@ +../util.py \ No newline at end of file diff --git a/docs/tr/sql-reference/statements/select.md b/docs/tr/sql-reference/statements/select.md index 8335028647b..bd9f5d72a81 100644 --- a/docs/tr/sql-reference/statements/select.md +++ b/docs/tr/sql-reference/statements/select.md @@ -1,6 +1,6 @@ --- machine_translated: true -machine_translated_rev: e8cd92bba3269f47787db090899f7c242adf7818 +machine_translated_rev: 0f7ef7704d018700049223525bad4a63911b6e70 toc_priority: 33 toc_title: SELECT --- @@ -34,7 +34,7 @@ Aşağıdaki yan tümceleri sorgu yürütme konveyör hemen hemen aynı sırada Sorgu atlarsa `DISTINCT`, `GROUP BY` ve `ORDER BY` CLA andus Andes and the `IN` ve `JOIN` alt sorgular, sorgu o (1) RAM miktarını kullanarak tamamen akış işlenecektir. Aksi takdirde, uygun kısıtlamalar belirtilmezse, sorgu çok fazla RAM tüketebilir: `max_memory_usage`, `max_rows_to_group_by`, `max_rows_to_sort`, `max_rows_in_distinct`, `max_bytes_in_distinct`, `max_rows_in_set`, `max_bytes_in_set`, `max_rows_in_join`, `max_bytes_in_join`, `max_bytes_before_external_sort`, `max_bytes_before_external_group_by`. Daha fazla bilgi için bölüme bakın “Settings”. Harici sıralama (geçici tabloları bir diske kaydetme) ve harici toplama kullanmak mümkündür. `The system does not have "merge join"`. -### Fık WİTHRA Ile {#with-clause} +### Fık WİTHRA ile {#with-clause} Bu bölüm, ortak tablo ifadeleri için destek sağlar ([CTE](https://en.wikipedia.org/wiki/Hierarchical_and_recursive_queries_in_SQL)), bazı sınırlamalar ile: 1. Özyinelemeli sorgular desteklenmiyor @@ -108,7 +108,7 @@ FROM ### Fık FROMRAS FROMINDAN {#select-from} FROM yan tümcesi atlanırsa, veriler `system.one` Tablo. -Bu `system.one` tablo tam olarak bir satır içerir (bu tablo diğer Dbms’lerde bulunan çift tablo ile aynı amacı yerine getirir). +Bu `system.one` tablo tam olarak bir satır içerir (bu tablo diğer Dbms'lerde bulunan çift tablo ile aynı amacı yerine getirir). Bu `FROM` yan tümcesi veri okumak için kaynak belirtir: @@ -164,13 +164,13 @@ Veri örneklemesinin özellikleri aşağıda listelenmiştir: | SAMPLE Clause Syntax | Açıklama | |----------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `SAMPLE k` | Burada `k` 0’dan 1’e kadar olan sayıdır.
Sorgu üzerinde yürütülür `k` verilerin kesir. Mesela, `SAMPLE 0.1` sorguyu verilerin %10’unda çalıştırır. [Daha fazla bilgi edinin](#select-sample-k) | +| `SAMPLE k` | Burada `k` 0'dan 1'e kadar olan sayıdır.
Sorgu üzerinde yürütülür `k` verilerin kesir. Mesela, `SAMPLE 0.1` sorguyu verilerin %10'unda çalıştırır. [Daha fazla bilgi edinin](#select-sample-k) | | `SAMPLE n` | Burada `n` yeterince büyük bir tamsayıdır.
Sorgu en az bir örnek üzerinde yürütülür `n` satırlar (ancak bundan önemli ölçüde daha fazla değil). Mesela, `SAMPLE 10000000` sorguyu en az 10.000.000 satır çalıştırır. [Daha fazla bilgi edinin](#select-sample-n) | -| `SAMPLE k OFFSET m` | Burada `k` ve `m` 0’dan 1’e kadar olan sayılardır.
Sorgu bir örnek üzerinde yürütülür `k` verilerin kesir. Örnek için kullanılan veriler, `m` bölme. [Daha fazla bilgi edinin](#select-sample-offset) | +| `SAMPLE k OFFSET m` | Burada `k` ve `m` 0'dan 1'e kadar olan sayılardır.
Sorgu bir örnek üzerinde yürütülür `k` verilerin kesir. Örnek için kullanılan veriler, `m` bölme. [Daha fazla bilgi edinin](#select-sample-offset) | #### SAMPLE K {#select-sample-k} -Burada `k` 0’dan 1’e kadar olan sayıdır (hem kesirli hem de ondalık gösterimler desteklenir). Mesela, `SAMPLE 1/2` veya `SAMPLE 0.5`. +Burada `k` 0'dan 1'e kadar olan sayıdır (hem kesirli hem de ondalık gösterimler desteklenir). Mesela, `SAMPLE 1/2` veya `SAMPLE 0.5`. İn a `SAMPLE k` fık ,ra, örnek alınır `k` verilerin kesir. Örnek aşağıda gösterilmiştir: @@ -196,7 +196,7 @@ Bu durumda, sorgu en az bir örnek üzerinde yürütülür `n` satırlar (ancak Veri okuma için minimum birim bir granül olduğundan (boyutu `index_granularity` ayar), granülün boyutundan çok daha büyük bir örnek ayarlamak mantıklıdır. -Kullanırken `SAMPLE n` yan tümce, verilerin hangi göreli yüzde işlendiğini bilmiyorsunuz. Yani toplam fonksiyonların çarpılması gereken katsayıyı bilmiyorsunuz. Kullan… `_sample_factor` sanal sütun yaklaşık sonucu almak için. +Kullanırken `SAMPLE n` yan tümce, verilerin hangi göreli yüzde işlendiğini bilmiyorsunuz. Yani toplam fonksiyonların çarpılması gereken katsayıyı bilmiyorsunuz. Kullan... `_sample_factor` sanal sütun yaklaşık sonucu almak için. Bu `_sample_factor` sütun dinamik olarak hesaplanan göreli katsayıları içerir. Bu sütun otomatik olarak oluşturulduğunda [oluşturmak](../../engines/table-engines/mergetree-family/mergetree.md#table_engine-mergetree-creating-a-table) belirtilen örnekleme anahtarına sahip bir tablo. Kullanım örnekleri `_sample_factor` sütun aşağıda gösterilmiştir. @@ -226,7 +226,7 @@ SAMPLE 10000000 #### SAMPLE K OFFSET M {#select-sample-offset} -Burada `k` ve `m` 0’dan 1’e kadar olan sayılardır. Örnekler aşağıda gösterilmiştir. +Burada `k` ve `m` 0'dan 1'e kadar olan sayılardır. Örnekler aşağıda gösterilmiştir. **Örnek 1** @@ -234,7 +234,7 @@ Burada `k` ve `m` 0’dan 1’e kadar olan sayılardır. Örnekler aşağıda g SAMPLE 1/10 ``` -Bu örnekte, örnek tüm verilerin 1/10’udur: +Bu örnekte, örnek tüm verilerin 1/10'udur: `[++------------]` @@ -244,13 +244,13 @@ Bu örnekte, örnek tüm verilerin 1/10’udur: SAMPLE 1/10 OFFSET 1/2 ``` -Burada, verilerin ikinci yarısından %10’luk bir örnek alınır. +Burada, verilerin ikinci yarısından %10'luk bir örnek alınır. `[------++------]` -### Dizi Jo JOİNİN Yan tüm Clausecesi {#select-array-join-clause} +### Dizi Jo JOİNİN yan tüm Clausecesi {#select-array-join-clause} -Yürüt allowsmeyi sağlar `JOIN` bir dizi veya iç içe veri yapısı ile. Niyet benzer [arrayJoin](../../sql-reference/functions/array-join.md#functions_arrayjoin) işlev, ancak işlevselliği daha geniştir. +Yürüt allowsmeyi sağlar `JOIN` bir dizi veya iç içe veri yapısı ile. Niyet benzer [arrayJoin](../functions/array-join.md#functions_arrayjoin) işlev, ancak işlevselliği daha geniştir. ``` sql SELECT @@ -405,9 +405,9 @@ ARRAY JOIN arr AS a, arrayEnumerate(arr) AS num; └───────┴─────────┴───┴─────┴─────────────────────┘ ``` -#### İç içe Veri yapısı Ile Dizi birleştirme {#array-join-with-nested-data-structure} +#### İç içe veri yapısı ile dizi birleştirme {#array-join-with-nested-data-structure} -`ARRAY`Jo “in” ile de çalışır [iç içe veri yapıları](../../sql-reference/data-types/nested-data-structures/nested.md). Örnek: +`ARRAY`Jo "in " ile de çalışır [iç içe veri yapıları](../../sql-reference/data-types/nested-data-structures/nested.md). Örnek: ``` sql CREATE TABLE nested_test @@ -534,7 +534,7 @@ FROM Tablo adları yerine belirtilebilir `` ve ``. Bu eşdeğerdir `SELECT * FROM table` alt sorgu, tablonun sahip olduğu özel bir durum dışında [Katmak](../../engines/table-engines/special/join.md) engine – an array prepared for joining. -#### Desteklenen Türleri `JOIN` {#select-join-types} +#### Desteklenen türleri `JOIN` {#select-join-types} - `INNER JOIN` (veya `JOIN`) - `LEFT JOIN` (veya `LEFT OUTER JOIN`) @@ -604,7 +604,776 @@ USING (equi_column1, ... equi_columnN, asof_column) Örneğin, aşağıdaki tabloları göz önünde bulundurun: -\`\`\` Metin -table\_1 table\_2 + table_1 table_2 + event | ev_time | user_id event | ev_time | user_id + ----------|---------|---------- ----------|---------|---------- + ... ... + event_1_1 | 12:00 | 42 event_2_1 | 11:59 | 42 + ... event_2_2 | 12:30 | 42 + event_1_2 | 13:00 | 42 event_2_3 | 13:00 | 42 + ... ... -olay / ev\_time / user\_id olay / ev\_time / user\_id +`ASOF JOIN` bir kullanıcı etkinliğinin zaman damgasını alabilir `table_1` ve bir olay bulmak `table_2` zaman damgasının olayın zaman damgasına en yakın olduğu yer `table_1` en yakın maç durumuna karşılık gelir. Varsa eşit zaman damgası değerleri en yakın olanıdır. Burada `user_id` sütun eşitlik üzerine katılmak için kullanılabilir ve `ev_time` sütun en yakın eşleşmeye katılmak için kullanılabilir. Örn oureğ inimizde, `event_1_1` ile Birleştir joinedilebilir `event_2_1` ve `event_1_2` ile Birleştir joinedilebilir `event_2_3`, ama `event_2_2` Birleştir .ilemez. + +!!! note "Not" + `ASOF` Jo isin is **değil** desteklenen [Katmak](../../engines/table-engines/special/join.md) masa motoru. + +Varsayılan strictness değerini ayarlamak için oturum yapılandırma parametresini kullanın [join\_default\_strictness](../../operations/settings/settings.md#settings-join_default_strictness). + +#### GLOBAL JOIN {#global-join} + +Normal kullanırken `JOIN`, sorgu uzak sunuculara gönderilir. Alt sorgular, doğru tabloyu yapmak için her biri üzerinde çalıştırılır ve birleştirme bu tablo ile gerçekleştirilir. Başka bir deyişle, doğru tablo her sunucuda ayrı ayrı oluşturulur. + +Kullanırken `GLOBAL ... JOIN`, önce istekte bulunan sunucu, doğru tabloyu hesaplamak için bir alt sorgu çalıştırır. Bu geçici tablo her uzak sunucuya geçirilir ve iletilen geçici verileri kullanarak sorgular çalıştırılır. + +Kullanırken dikkatli olun `GLOBAL`. Daha fazla bilgi için bölüme bakın [Dağıtılmış alt sorgular](#select-distributed-subqueries). + +#### Kullanım Önerileri {#usage-recommendations} + +Çalışırken bir `JOIN`, sorgunun diğer aşamaları ile ilgili olarak yürütme sırasının optimizasyonu yoktur. Birleştirme (sağ tablodaki bir arama), filtrelemeden önce çalıştırılır `WHERE` ve toplamadan önce. İşlem sırasını açıkça ayarlamak için, bir `JOIN` bir alt sorgu ile alt sorgu. + +Örnek: + +``` sql +SELECT + CounterID, + hits, + visits +FROM +( + SELECT + CounterID, + count() AS hits + FROM test.hits + GROUP BY CounterID +) ANY LEFT JOIN +( + SELECT + CounterID, + sum(Sign) AS visits + FROM test.visits + GROUP BY CounterID +) USING CounterID +ORDER BY hits DESC +LIMIT 10 +``` + +``` text +┌─CounterID─┬───hits─┬─visits─┐ +│ 1143050 │ 523264 │ 13665 │ +│ 731962 │ 475698 │ 102716 │ +│ 722545 │ 337212 │ 108187 │ +│ 722889 │ 252197 │ 10547 │ +│ 2237260 │ 196036 │ 9522 │ +│ 23057320 │ 147211 │ 7689 │ +│ 722818 │ 90109 │ 17847 │ +│ 48221 │ 85379 │ 4652 │ +│ 19762435 │ 77807 │ 7026 │ +│ 722884 │ 77492 │ 11056 │ +└───────────┴────────┴────────┘ +``` + +Alt sorgular, belirli bir alt sorgudan bir sütuna başvurmak için adları ayarlamanıza veya bunları kullanmanıza izin vermez. +Belirtilen sütunlar `USING` her iki alt sorguda da aynı adlara sahip olmalı ve diğer sütunların farklı olarak adlandırılması gerekir. Alt sorgulardaki sütunların adlarını değiştirmek için diğer adları kullanabilirsiniz (örnek, diğer adları kullanır `hits` ve `visits`). + +Bu `USING` yan tümcesi, bu sütunların eşitliğini oluşturan katılmak için bir veya daha fazla sütun belirtir. Sütunların listesi parantez olmadan ayarlanır. Daha karmaşık birleştirme koşulları desteklenmez. + +Sağ tablo (alt sorgu sonucu) RAM'de bulunur. Yeterli bellek yoksa, bir `JOIN`. + +Her seferinde bir sorgu aynı ile çalıştırılır `JOIN`, sonuç önbelleğe alınmadığı için alt sorgu yeniden çalıştırılır. Bunu önlemek için özel [Katmak](../../engines/table-engines/special/join.md) her zaman RAM'de olan birleştirme için hazırlanmış bir dizi olan tablo motoru. + +Bazı durumlarda, kullanımı daha verimlidir `IN` yerine `JOIN`. +Çeşitli türleri arasında `JOIN` en verimli `ANY LEFT JOIN`, sonraları `ANY INNER JOIN`. En az verimli `ALL LEFT JOIN` ve `ALL INNER JOIN`. + +Bir ihtiyacınız varsa `JOIN` boyut tablolarıyla birleştirmek için (bunlar, reklam kampanyalarının adları gibi boyut özelliklerini içeren nispeten küçük tablolardır), bir `JOIN` her sorgu için doğru tabloya yeniden erişilmesi nedeniyle çok uygun olmayabilir. Bu durumlar için, bir “external dictionaries” yerine kullanmanız gereken özellik `JOIN`. Daha fazla bilgi için bölüme bakın [Dış söz dictionarieslükler](../dictionaries/external-dictionaries/external-dicts.md). + +**Bellek Sınırlamaları** + +ClickHouse kullanır [has joinh Jo joinin](https://en.wikipedia.org/wiki/Hash_join) algoritma. ClickHouse alır `` ve RAM'de bunun için bir karma tablo oluşturur. Birleştirme işlemi bellek tüketimini kısıtlamanız gerekiyorsa aşağıdaki ayarları kullanın: + +- [max\_rows\_in\_join](../../operations/settings/query-complexity.md#settings-max_rows_in_join) — Limits number of rows in the hash table. +- [max\_bytes\_in\_join](../../operations/settings/query-complexity.md#settings-max_bytes_in_join) — Limits size of the hash table. + +Bu sınırlardan herhangi birine ulaşıldığında, ClickHouse [join\_overflow\_mode](../../operations/settings/query-complexity.md#settings-join_overflow_mode) ayar talimatı verir. + +#### Boş veya boş hücrelerin işlenmesi {#processing-of-empty-or-null-cells} + +Tabloları birleştirirken, boş hücreler görünebilir. Ayar [join\_use\_nulls](../../operations/settings/settings.md#join_use_nulls) Clickhouse'un bu hücreleri nasıl doldurduğunu tanımlayın. + +Eğer... `JOIN` key Ares are [Nullable](../data-types/nullable.md) alanlar, anahtarlardan en az birinin değeri olan satırlar [NULL](../syntax.md#null-literal) Birleştir .ilmez. + +#### Sözdizimi Sınırlamaları {#syntax-limitations} + +Çoklu için `JOIN` CLA aus AES in a single `SELECT` sorgu: + +- Aracılığıyla tüm sütunları alarak `*` yalnızca tablolar birleştirildiğinde kullanılabilir, alt sorgular değil. +- Bu `PREWHERE` fıkra availablesı mevcut değildir. + +İçin `ON`, `WHERE`, ve `GROUP BY` yanlar: + +- Keyfi ifadeler kullanılamaz `ON`, `WHERE`, ve `GROUP BY` yan tümceleri, ancak bir ifade tanımlayabilirsiniz `SELECT` yan tümce ve daha sonra bu yan tümcelerde bir takma ad ile kullanın. + +### WHERE {#select-where} + +Bir WHERE yan tümcesi varsa, uint8 türüne sahip bir ifade içermelidir. Bu genellikle karşılaştırma ve mantıksal işleçlere sahip bir ifadedir. +Bu ifade, diğer tüm dönüşümlerden önce verileri filtrelemek için kullanılır. + +Dizinler veritabanı tablo altyapısı tarafından destekleniyorsa, ifade dizinleri kullanma yeteneği değerlendirilir. + +### PREWHERE maddesi {#prewhere-clause} + +Bu madde, WHERE maddesi ile aynı anlama sahiptir. Fark, verilerin tablodan okunmasıdır. +Prewhere kullanırken, önce yalnızca prewhere yürütmek için gerekli olan sütunlar okunur. Daha sonra sorguyu çalıştırmak için gerekli olan diğer sütunlar okunur, ancak yalnızca PREWHERE ifadesinin doğru olduğu bloklar. + +Sorgudaki sütunların azınlığı tarafından kullanılan, ancak güçlü veri filtrasyonu sağlayan filtreleme koşulları varsa, PREWHERE kullanmak mantıklıdır. Bu, okunacak veri hacmini azaltır. + +Örneğin, çok sayıda sütun ayıklayan, ancak yalnızca birkaç sütun için filtrelemeye sahip olan sorgular için PREWHERE yazmak yararlıdır. + +PREWHERE sadece tablolar tarafından desteklenmektedir `*MergeTree` aile. + +Bir sorgu aynı anda prewhere ve WHERE belirtebilirsiniz. Bu durumda, PREWHERE nerede önce gelir. + +Eğer... ‘optimize\_move\_to\_prewhere’ ayar 1 olarak ayarlanır ve prewhere atlanır, sistem otomatik olarak ifadelerin parçalarını prewhere yerden taşımak için sezgisel kullanır. + +### GROUP BY Fık Clausera {#select-group-by-clause} + +Bu, sütun yönelimli bir DBMS'NİN en önemli parçalarından biridir. + +Bir GROUP BY yan tümcesi varsa, ifadelerin bir listesini içermelidir. Her ifade burada bir “key”. +SELECT, HAVİNG ve ORDER BY yan tümcelerindeki tüm ifadeler, anahtarlardan veya toplama işlevlerinden hesaplanmalıdır. Başka bir deyişle, tablodan seçilen her sütun, anahtarlarda veya toplama işlevlerinde kullanılmalıdır. + +Bir sorgu toplama işlevleri içinde yalnızca tablo sütunları içeriyorsa, GROUP BY yan tümcesi atlanabilir ve boş bir anahtar kümesi tarafından toplama varsayılır. + +Örnek: + +``` sql +SELECT + count(), + median(FetchTiming > 60 ? 60 : FetchTiming), + count() - sum(Refresh) +FROM hits +``` + +Bununla birlikte, standart SQL'İN aksine, tabloda herhangi bir satır yoksa (ya hiç yok ya da FİLTRELENECEK yeri kullandıktan sonra yok), boş bir sonuç döndürülür ve toplam işlevlerin başlangıç değerlerini içeren satırlardan birinin sonucu değil. + +Mysql'in aksine (ve standart SQL'E uygun olarak), bir anahtar veya toplama işlevinde olmayan (sabit ifadeler hariç) bazı sütunun bir değerini alamazsınız. Bu sorunu gidermek için kullanabilirsiniz ‘any’ toplama işlevi (ilk karşılaşılan değeri al) veya ‘min/max’. + +Örnek: + +``` sql +SELECT + domainWithoutWWW(URL) AS domain, + count(), + any(Title) AS title -- getting the first occurred page header for each domain. +FROM hits +GROUP BY domain +``` + +Karşılaşılan her farklı anahtar değeri için GROUP BY, bir dizi toplama işlevi değeri hesaplar. + +GROUP BY dizi sütunları için desteklenmiyor. + +Bir sabit, toplam işlevler için bağımsız değişken olarak belirtilemez. Örnek: Toplam (1). Bunun yerine, sabitten kurtulabilirsiniz. Örnek: `count()`. + +#### NULL işleme {#null-processing} + +Gruplama için ClickHouse yorumlar [NULL](../syntax.md) bir değer olarak ve `NULL=NULL`. + +İşte bunun ne anlama geldiğini göstermek için bir örnek. + +Bu tabloya sahip olduğunuzu varsayalım: + +``` text +┌─x─┬────y─┐ +│ 1 │ 2 │ +│ 2 │ ᴺᵁᴸᴸ │ +│ 3 │ 2 │ +│ 3 │ 3 │ +│ 3 │ ᴺᵁᴸᴸ │ +└───┴──────┘ +``` + +Sorgu `SELECT sum(x), y FROM t_null_big GROUP BY y` res inult ins in: + +``` text +┌─sum(x)─┬────y─┐ +│ 4 │ 2 │ +│ 3 │ 3 │ +│ 5 │ ᴺᵁᴸᴸ │ +└────────┴──────┘ +``` + +Bunu görebilirsiniz `GROUP BY` için `y = NULL` özetlemek `x`, sanki `NULL` bu değerdir. + +İçin birkaç anahtar geç iferseniz `GROUP BY`, sonuç size seçimin tüm kombinasyonlarını verecek, sanki `NULL` belirli bir değer vardı. + +#### Toplamlar değiştirici ile {#with-totals-modifier} + +Toplamları değiştirici ile belirtilirse, başka bir satır hesaplanır. Bu satır, varsayılan değerleri (sıfırlar veya boş satırlar) içeren anahtar sütunlara ve tüm satırlar arasında hesaplanan değerlerle toplam işlevlerin sütunlarına sahip olacaktır ( “total” değerler). + +Bu ekstra satır, diğer satırlardan ayrı olarak JSON\*, TabSeparated\* ve Pretty\* formatlarında çıktıdır. Diğer biçimlerde, bu satır çıktı değildir. + +JSON \* formatlarında, bu satır ayrı olarak çıktı ‘totals’ alan. TabSeparated \* biçimlerinde satır, boş bir satırdan önce gelen ana sonuçtan sonra gelir (diğer verilerden sonra). Pretty \* biçimlerinde, satır ana sonuçtan sonra ayrı bir tablo olarak çıktılanır. + +`WITH TOTALS` sahip olduğunda farklı şekillerde çalıştırılabilir. Davranış bağlıdır ‘totals\_mode’ ayar. +Varsayılan olarak, `totals_mode = 'before_having'`. Bu durumda, ‘totals’ olan ve geç onesmeyen satırlar da dahil olmak üzere tüm satırlar arasında hesaplanır. ‘max\_rows\_to\_group\_by’. + +Diğer alternatifler, yalnızca sahip olan satırları içerir ‘totals’, ve ayar ile farklı davranır `max_rows_to_group_by` ve `group_by_overflow_mode = 'any'`. + +`after_having_exclusive` – Don't include rows that didn't pass through `max_rows_to_group_by`. Başka bir deyişle, ‘totals’ eğer olduğu gibi daha az veya aynı sayıda satıra sahip olacak `max_rows_to_group_by` atlanmış. + +`after_having_inclusive` – Include all the rows that didn't pass through ‘max\_rows\_to\_group\_by’ içinde ‘totals’. Başka bir deyişle, ‘totals’ daha fazla veya aynı sayıda satır olacak `max_rows_to_group_by` atlanmış. + +`after_having_auto` – Count the number of rows that passed through HAVING. If it is more than a certain amount (by default, 50%), include all the rows that didn't pass through ‘max\_rows\_to\_group\_by’ içinde ‘totals’. Aksi takdirde, bunları dahil etmeyin. + +`totals_auto_threshold` – By default, 0.5. The coefficient for `after_having_auto`. + +Eğer `max_rows_to_group_by` ve `group_by_overflow_mode = 'any'` kullanıl ,mıyor, tüm vary ,asyonları `after_having` aynıdır ve bunlardan herhangi birini kullanabilirsiniz (Örneğin, `after_having_auto`). + +JOIN yan tümcesindeki alt sorgular da dahil olmak üzere alt sorgulardaki TOPLAMLARLA birlikte kullanabilirsiniz (bu durumda, ilgili toplam değerler birleştirilir). + +#### Harici bellekte grupla {#select-group-by-in-external-memory} + +Sırasında bellek kullanımını kısıtlamak için diske geçici veri boşaltma etkinleştirebilirsiniz `GROUP BY`. +Bu [max\_bytes\_before\_external\_group\_by](../../operations/settings/settings.md#settings-max_bytes_before_external_group_by) ayar damping için eşik RAM tüketimini belirler `GROUP BY` dosya sistemine geçici veri. 0 (varsayılan) olarak ayarlanırsa, devre dışı bırakılır. + +Kullanırken `max_bytes_before_external_group_by` öneririz ayarladığınız `max_memory_usage` yüksek iki katı daha fazla. Bu, toplanmanın iki aşaması olduğundan gereklidir: tarihi okumak ve ara verileri (1) oluşturmak ve ara verileri (2) birleştirmek. Dosya sistemine veri damping yalnızca aşama 1 sırasında oluşabilir. Geçici veriler dökülmediyse, aşama 2, aşama 1'deki gibi aynı miktarda bellek gerektirebilir. + +Örneğin, [max\_memory\_usage](../../operations/settings/settings.md#settings_max_memory_usage) 100000000 olarak ayarlandı ve harici toplama kullanmak istiyorsanız, ayarlamak mantıklı `max_bytes_before_external_group_by` için 10000000000 ve max\_memory\_usage için 20000000000. Harici toplama tetiklendiğinde (en az bir geçici veri dökümü varsa), maksimum RAM tüketimi sadece biraz daha fazladır `max_bytes_before_external_group_by`. + +Dağıtılmış sorgu işleme ile uzak sunucularda harici toplama gerçekleştirilir. İstekte bulunan sunucunun yalnızca az miktarda RAM kullanması için `distributed_aggregation_memory_efficient` 1'e. + +Verileri diske temizlerken ve uzak sunuculardan gelen sonuçları birleştirirken `distributed_aggregation_memory_efficient` ayarı etkin, tüketir kadar `1/256 * the_number_of_threads` toplam RAM miktarından. + +Harici toplama etkinleştirildiğinde, daha az olsaydı `max_bytes_before_external_group_by` of data (i.e. data was not flushed), the query runs just as fast as without external aggregation. If any temporary data was flushed, the run time will be several times longer (approximately three times). + +Eğer bir `ORDER BY` ile bir `LIMIT` sonra `GROUP BY`, daha sonra kullanılan RAM miktarı veri miktarına bağlıdır `LIMIT` bütün masada değil. Ama eğer `ORDER BY` yok `LIMIT`, harici sıralamayı etkinleştirmeyi unutmayın (`max_bytes_before_external_sort`). + +### Madde ile sınır {#limit-by-clause} + +İle bir sorgu `LIMIT n BY expressions` fık thera birinci `n` her bir farklı değer için satırlar `expressions`. Anahtarı `LIMIT BY` herhangi bir sayıda içerebilir [ifadeler](../syntax.md#syntax-expressions). + +ClickHouse aşağıdaki sözdizimini destekler: + +- `LIMIT [offset_value, ]n BY expressions` +- `LIMIT n OFFSET offset_value BY expressions` + +Sorgu işleme sırasında ClickHouse, sıralama anahtarı tarafından sipariş edilen verileri seçer. Sıralama anahtarı açıkça bir [ORDER BY](#select-order-by) yan tümcesi veya örtük bir özellik olarak tablo altyapısı. Sonra ClickHouse geçerlidir `LIMIT n BY expressions` ve ilk döndürür `n` her farklı kombinasyon için satırlar `expressions`. Eğer `OFFSET` Belirtilen, daha sonra farklı bir kombinasyonuna ait her veri bloğu için `expressions`, ClickHouse atlar `offset_value` bloğun başından itibaren satır sayısı ve en fazla döndürür `n` sonuç olarak satırlar. Eğer `offset_value` veri bloğundaki satır sayısından daha büyük olan ClickHouse, bloktan sıfır satır döndürür. + +`LIMIT BY` ilgili değildir `LIMIT`. Her ikisi de aynı sorguda kullanılabilir. + +**Örnekler** + +Örnek tablo: + +``` sql +CREATE TABLE limit_by(id Int, val Int) ENGINE = Memory; +INSERT INTO limit_by values(1, 10), (1, 11), (1, 12), (2, 20), (2, 21); +``` + +Sorgular: + +``` sql +SELECT * FROM limit_by ORDER BY id, val LIMIT 2 BY id +``` + +``` text +┌─id─┬─val─┐ +│ 1 │ 10 │ +│ 1 │ 11 │ +│ 2 │ 20 │ +│ 2 │ 21 │ +└────┴─────┘ +``` + +``` sql +SELECT * FROM limit_by ORDER BY id, val LIMIT 1, 2 BY id +``` + +``` text +┌─id─┬─val─┐ +│ 1 │ 11 │ +│ 1 │ 12 │ +│ 2 │ 21 │ +└────┴─────┘ +``` + +Bu `SELECT * FROM limit_by ORDER BY id, val LIMIT 2 OFFSET 1 BY id` sorgu aynı sonucu verir. + +Aşağıdaki sorgu, her biri için en iyi 5 yönlendiriciyi döndürür `domain, device_type` toplamda maksimum 100 satır ile eşleştirin (`LIMIT n BY + LIMIT`). + +``` sql +SELECT + domainWithoutWWW(URL) AS domain, + domainWithoutWWW(REFERRER_URL) AS referrer, + device_type, + count() cnt +FROM hits +GROUP BY domain, referrer, device_type +ORDER BY cnt DESC +LIMIT 5 BY domain, device_type +LIMIT 100 +``` + +### Fık HAVİNGRA olması {#having-clause} + +WHERE yan tümcesine benzer şekilde, gruptan sonra alınan sonucun filtrelenmesine izin verir. +NEREDE ve sonra gerçekleştirilmesi sırasında toplama (GRUP) TARAFINDAN daha önce yapılacağı YERİ olan, farklı OLMASI. +Toplama yapılmazsa, sahip kullanılamaz. + +### ORDER BY FLA BYGE {#select-order-by} + +ORDER BY yan tümcesi, her birine DESC veya ASC (sıralama yönü) atanabilen ifadelerin bir listesini içerir. Yön belirtilmezse, ASC varsayılır. ASC artan sırada sıralanır ve azalan sırada DESC edilir. Sıralama yönü, tüm listeye değil, tek bir ifade için geçerlidir. Örnek: `ORDER BY Visits DESC, SearchPhrase` + +Dize değerlerine göre sıralamak için harmanlama (karşılaştırma) belirtebilirsiniz. Örnek: `ORDER BY SearchPhrase COLLATE 'tr'` - artan sırayla anahtar kelimeye göre sıralama için, Türk alfabesini kullanarak, büyük / küçük harf duyarsız, dizelerin UTF-8 kodlanmış olduğunu varsayarak. Harmanlama belirtilebilir veya her ifade için bağımsız olarak sırayla değil. ASC veya DESC belirtilirse, harmanla ondan sonra belirtilir. Harmanlama kullanırken, sıralama her zaman büyük / küçük harf duyarsızdır. + +Harmanlama ile sıralama, baytlara göre normal sıralamadan daha az verimli olduğundan, yalnızca az sayıda satırın son sıralaması için harmanlamayı kullanmanızı öneririz. + +Sıralama ifadeleri listesi için aynı değerlere sahip olan satırlar, isteğe bağlı bir sırayla çıktılanır ve bu da nondeterministic (her seferinde farklı) olabilir. +ORDER BY yan tümcesi atlanırsa, satırların sırası da tanımsızdır ve nondeterministic de olabilir. + +`NaN` ve `NULL` sıralama sırası: + +- Değiştirici ile `NULLS FIRST` — First `NULL`, sonraları `NaN`, sonra diğer değerler. +- Değiştirici ile `NULLS LAST` — First the values, then `NaN`, sonraları `NULL`. +- Default — The same as with the `NULLS LAST` değiştirici. + +Örnek: + +Masa için + +``` text +┌─x─┬────y─┐ +│ 1 │ ᴺᵁᴸᴸ │ +│ 2 │ 2 │ +│ 1 │ nan │ +│ 2 │ 2 │ +│ 3 │ 4 │ +│ 5 │ 6 │ +│ 6 │ nan │ +│ 7 │ ᴺᵁᴸᴸ │ +│ 6 │ 7 │ +│ 8 │ 9 │ +└───┴──────┘ +``` + +Sorguyu Çalıştır `SELECT * FROM t_null_nan ORDER BY y NULLS FIRST` olmak: + +``` text +┌─x─┬────y─┐ +│ 1 │ ᴺᵁᴸᴸ │ +│ 7 │ ᴺᵁᴸᴸ │ +│ 1 │ nan │ +│ 6 │ nan │ +│ 2 │ 2 │ +│ 2 │ 2 │ +│ 3 │ 4 │ +│ 5 │ 6 │ +│ 6 │ 7 │ +│ 8 │ 9 │ +└───┴──────┘ +``` + +Kayan nokta numaraları sıralandığında, Nan'lar diğer değerlerden ayrıdır. Sıralama sırasına bakılmaksızın, Nan'lar sonunda gelir. Başka bir deyişle, artan sıralama için, diğer tüm sayılardan daha büyük gibi yerleştirilirken, azalan sıralama için, diğerlerinden daha küçük gibi yerleştirilirler. + +Tarafından siparişe ek olarak yeterince küçük bir sınır belirtilirse daha az RAM kullanılır. Aksi takdirde, harcanan bellek miktarı sıralama için veri hacmi ile orantılıdır. Dağıtılmış sorgu işleme için GROUP BY atlanırsa, sıralama kısmen uzak sunucularda yapılır ve sonuçları istekte bulunan sunucuda birleştirilir. Bu, dağıtılmış sıralama için, sıralanacak veri hacminin tek bir sunucudaki bellek miktarından daha büyük olabileceği anlamına gelir. + +Yeterli RAM yoksa, harici bellekte sıralama yapmak mümkündür (bir diskte geçici dosyalar oluşturmak). Ayarı kullan `max_bytes_before_external_sort` bu amaçla. 0 (varsayılan) olarak ayarlanırsa, dış sıralama devre dışı bırakılır. Etkinleştirilirse, sıralanacak veri hacmi belirtilen bayt sayısına ulaştığında, toplanan veriler sıralanır ve geçici bir dosyaya dökülür. Tüm veriler okunduktan sonra, sıralanmış tüm dosyalar birleştirilir ve sonuçlar çıktılanır. Dosyalar yapılandırmada /var/lib/clickhouse/tmp/ dizinine yazılır (varsayılan olarak, ancak ‘tmp\_path’ bu ayarı değiştirmek için parametre). + +Bir sorguyu çalıştırmak, daha fazla bellek kullanabilir ‘max\_bytes\_before\_external\_sort’. Bu nedenle, bu ayarın önemli ölçüde daha küçük bir değere sahip olması gerekir ‘max\_memory\_usage’. Örnek olarak, sunucunuzda 128 GB RAM varsa ve tek bir sorgu çalıştırmanız gerekiyorsa, ‘max\_memory\_usage’ 100 GB ve ‘max\_bytes\_before\_external\_sort’ için 80 GB. + +Harici sıralama, RAM'de sıralamaktan çok daha az etkili çalışır. + +### SELECT CLA Clauseuse {#select-select} + +[İfadeler](../syntax.md#syntax-expressions) belirtilen `SELECT` yukarıda açıklanan yan tümcelerde tüm işlemler tamamlandıktan sonra yan tümce hesaplanır. Bu ifadeler, sonuçtaki ayrı satırlara uygulanıyormuş gibi çalışır. İf ifadeleri `SELECT` yan tümcesi toplama işlevleri içerir, daha sonra ClickHouse toplama işlevleri ve argümanları sırasında kullanılan ifadeleri işler. [GROUP BY](#select-group-by-clause) toplanma. + +Sonuçtaki tüm sütunları eklemek istiyorsanız, yıldız işaretini kullanın (`*`) sembol. Mesela, `SELECT * FROM ...`. + +Sonuçtaki bazı sütunları bir ile eşleştirmek için [re2](https://en.wikipedia.org/wiki/RE2_(software)) düzenli ifade, kullanabilirsiniz `COLUMNS` ifade. + +``` sql +COLUMNS('regexp') +``` + +Örneğin, tabloyu düşünün: + +``` sql +CREATE TABLE default.col_names (aa Int8, ab Int8, bc Int8) ENGINE = TinyLog +``` + +Aşağıdaki sorgu içeren tüm sütunlardan veri seçer `a` onların adına sembol. + +``` sql +SELECT COLUMNS('a') FROM col_names +``` + +``` text +┌─aa─┬─ab─┐ +│ 1 │ 1 │ +└────┴────┘ +``` + +Seçilen sütunlar alfabetik sırayla döndürülür. + +Birden fazla kullanabilirsiniz `COLUMNS` bir sorgudaki ifadeler ve bunlara işlevler uygulanır. + +Mesela: + +``` sql +SELECT COLUMNS('a'), COLUMNS('c'), toTypeName(COLUMNS('c')) FROM col_names +``` + +``` text +┌─aa─┬─ab─┬─bc─┬─toTypeName(bc)─┐ +│ 1 │ 1 │ 1 │ Int8 │ +└────┴────┴────┴────────────────┘ +``` + +Tarafından döndürülen her sütun `COLUMNS` ifade, işleve ayrı bir bağımsız değişken olarak geçirilir. Ayrıca, diğer argümanları da destekliyorsa işleve iletebilirsiniz. Fonksiyonları kullanırken dikkatli olun. Bir işlev, kendisine ilettiğiniz bağımsız değişken sayısını desteklemiyorsa, ClickHouse bir istisna atar. + +Mesela: + +``` sql +SELECT COLUMNS('a') + COLUMNS('c') FROM col_names +``` + +``` text +Received exception from server (version 19.14.1): +Code: 42. DB::Exception: Received from localhost:9000. DB::Exception: Number of arguments for function plus doesn't match: passed 3, should be 2. +``` + +Bu örnekte, `COLUMNS('a')` iki sütun döndürür: `aa` ve `ab`. `COLUMNS('c')` ret theur thens the `bc` sütun. Bu `+` operatör 3 argüman için geçerli olamaz, Bu nedenle ClickHouse ilgili mesajla bir istisna atar. + +Eşleşen sütunlar `COLUMNS` ifade farklı veri türlerine sahip olabilir. Eğer `COLUMNS` herhangi bir sütun eşleşmiyor ve sadece ifadedir `SELECT`, ClickHouse bir istisna atar. + +### Farklı Madde {#select-distinct} + +DISTINCT belirtilirse, sonuçta tam olarak eşleşen satır kümelerinin dışında yalnızca tek bir satır kalır. +Sonuç, grup tarafından, toplama işlevleri olmadan SEÇ'TE belirtilen tüm alanlar arasında belirtildiği gibi aynı olacaktır. Ancak gruptan birkaç farklılık var: + +- DI DİSTİNCTST DİSTİNCTINC GROUPT GROUP BY ile birlikte uygulanabilir. +- ORDER BY atlandığında ve LİMİT tanımlandığında, gerekli sayıda farklı satır okunduktan hemen sonra sorgu çalışmayı durdurur. +- Veri blokları, işlenirken, tüm sorgunun çalışmayı bitirmesini beklemeden çıktılanır. + +Select en az bir dizi sütunu varsa DISTINCT desteklenmez. + +`DISTINCT` ile çalışır [NULL](../syntax.md) sanki `NULL` belirli bir değer ve `NULL=NULL`. Diğer bir deyişle, içinde `DISTINCT` sonuçlar, farklı kombinasyonlar ile `NULL` yalnızca bir kez meydana gelir. + +ClickHouse kullanarak destekler `DISTINCT` ve `ORDER BY` bir sorguda farklı sütunlar için yan tümceleri. Bu `DISTINCT` fık thera önce Yürüt theülür `ORDER BY` yan. + +Örnek tablo: + +``` text +┌─a─┬─b─┐ +│ 2 │ 1 │ +│ 1 │ 2 │ +│ 3 │ 3 │ +│ 2 │ 4 │ +└───┴───┘ +``` + +İle veri seç whenerken `SELECT DISTINCT a FROM t1 ORDER BY b ASC` sorgu, aşağıdaki sonucu elde ederiz: + +``` text +┌─a─┐ +│ 2 │ +│ 1 │ +│ 3 │ +└───┘ +``` + +Sıralama yönünü değiştirirsek `SELECT DISTINCT a FROM t1 ORDER BY b DESC` alalım şu sonuç: + +``` text +┌─a─┐ +│ 3 │ +│ 1 │ +│ 2 │ +└───┘ +``` + +Satır `2, 4` sıralamadan önce kesildi. + +Sorguları programlarken bu uygulama özgüllüğünü dikkate alın. + +### LİMİT maddesi {#limit-clause} + +`LIMIT m` ilk seçmenizi sağlar `m` sonuçtan satırlar. + +`LIMIT n, m` ilk seçmenizi sağlar `m` ilkini atladıktan sonra sonuçtan satırlar `n` satırlar. Bu `LIMIT m OFFSET n` sözdizimi de desteklenmektedir. + +`n` ve `m` negatif olmayan tamsayılar olmalıdır. + +Eğer yoksa bir `ORDER BY` sonuçları açıkça sıralayan yan tümce, sonuç keyfi ve belirsiz olabilir. + +### Birlik tüm Fık Clausera {#union-all-clause} + +Herhangi bir sayıda sorguyu birleştirmek için tümünü bir araya getir'i kullanabilirsiniz. Örnek: + +``` sql +SELECT CounterID, 1 AS table, toInt64(count()) AS c + FROM test.hits + GROUP BY CounterID + +UNION ALL + +SELECT CounterID, 2 AS table, sum(Sign) AS c + FROM test.visits + GROUP BY CounterID + HAVING c > 0 +``` + +Sadece birlik tüm desteklenmektedir. Düzenli birlik (birlik DISTINCT) desteklenmiyor. UNION DISTINCT gerekiyorsa, UNION ALL içeren bir alt sorgudan SELECT DISTINCT yazabilirsiniz. + +UNİON ALL'IN bir parçası olan sorgular aynı anda çalıştırılabilir ve sonuçları birlikte karıştırılabilir. + +Sonuçların yapısı (sütun sayısı ve türü) sorgular için eşleşmelidir. Ancak sütun adları farklı olabilir. Bu durumda, nihai sonuç için sütun adları ilk sorgudan alınacaktır. Sendikalar için Tip döküm yapılır. Örneğin, birleştirilen iki sorgu, non ile aynı alana sahipse-`Nullable` ve `Nullable` uyumlu bir türden tür, ortaya çıkan `UNION ALL` has a `Nullable` türü alanı. + +UNİON'UN bir parçası olan sorgular parantez içine alınamaz. ORDER BY ve LİMİT, nihai sonuca değil, ayrı sorgulara uygulanır. Nihai sonuca bir dönüştürme uygulamanız gerekiyorsa, tüm sorguları UNION ALL ile FROM yan tümcesinde bir alt sorguya koyabilirsiniz. + +### OUTFİLE fıkra içine {#into-outfile-clause} + +Add the `INTO OUTFILE filename` yan tümcesi (burada dosyaadı bir dize değişmez) belirtilen dosyaya sorgu çıktısını yeniden yönlendirmek için. +MySQL aksine, dosya istemci tarafında oluşturulur. Aynı dosya adı ile bir dosya zaten varsa, sorgu başarısız olur. +Bu işlevsellik, komut satırı istemcisinde ve clickhouse-local'de kullanılabilir (HTTP arabirimi üzerinden gönderilen bir sorgu başarısız olur). + +Varsayılan çıkış biçimi TabSeparated (komut satırı istemci toplu iş modunda olduğu gibi). + +### FORMAT CLA Clauseuse {#format-clause} + +Belirtmek ‘FORMAT format’ belirtilen herhangi bir biçimde veri almak için. +Bunu kolaylık sağlamak veya döküntüler oluşturmak için kullanabilirsiniz. +Daha fazla bilgi için bölüme bakın “Formats”. +FORMAT yan tümcesi atlanırsa, db'ye erişmek için kullanılan hem ayarlara hem de arabirime bağlı olan varsayılan biçim kullanılır. HTTP arabirimi ve toplu iş modunda komut satırı istemcisi için varsayılan biçim TabSeparated. Etkileşimli modda komut satırı istemcisi için varsayılan biçim PrettyCompact (çekici ve kompakt tablolara sahiptir). + +Komut satırı istemcisini kullanırken, veri istemciye bir iç verimli biçimde geçirilir. İstemci, sorgunun FORMAT yan tümcesini bağımsız olarak yorumlar ve verilerin kendisini biçimlendirir (böylece ağı ve sunucuyu yükten kurtarır). + +### Operatör İNLERDE {#select-in-operators} + +Bu `IN`, `NOT IN`, `GLOBAL IN`, ve `GLOBAL NOT IN` operatörler, işlevleri oldukça zengin olduğu için ayrı ayrı kaplıdır. + +Operatörün sol tarafı tek bir sütun veya bir tuple'dır. + +Örnekler: + +``` sql +SELECT UserID IN (123, 456) FROM ... +SELECT (CounterID, UserID) IN ((34, 123), (101500, 456)) FROM ... +``` + +Sol tarafı dizindeki tek bir sütun ve sağ tarafı sabitler kümesidir, sistem sorguyu işlemek için dizin kullanır. + +Don't list too many values explicitly (i.e. millions). If a data set is large, put it in a temporary table (for example, see the section “External data for query processing”), sonra bir alt sorgu kullanın. + +Operatörün sağ tarafı, sabit ifadeler kümesi, sabit ifadelere sahip bir dizi dizi (yukarıdaki örneklerde gösterilmiştir) veya bir veritabanı tablosunun adı veya parantez içinde alt sorgu olabilir. + +Operatörün sağ tarafı bir tablonun adı ise (örneğin, `UserID IN users`), bu alt sorguya eşdeğerdir `UserID IN (SELECT * FROM users)`. Sorgu ile birlikte gönderilen dış verilerle çalışırken bunu kullanın. Örneğin, sorgu için yüklenen kullanıcı kimlikleri kümesi ile birlikte gönderilebilir ‘users’ filtrelenmesi gereken geçici tablo. + +Operatörün sağ tarafında Set altyapısı (her zaman RAM'de hazırlanmış bir veri kümesi) olan bir tablo adı ise, veri kümesi her sorgu için yeniden oluşturulmaz. + +Alt sorgu, tuples süzme için birden fazla sütun belirtebilir. +Örnek: + +``` sql +SELECT (CounterID, UserID) IN (SELECT CounterID, UserID FROM ...) FROM ... +``` + +In işlecinin solundaki ve sağındaki sütunlar aynı türe sahip olmalıdır. + +In işleci ve alt sorgu, toplam işlevleri ve lambda işlevleri de dahil olmak üzere sorgunun herhangi bir bölümünde oluşabilir. +Örnek: + +``` sql +SELECT + EventDate, + avg(UserID IN + ( + SELECT UserID + FROM test.hits + WHERE EventDate = toDate('2014-03-17') + )) AS ratio +FROM test.hits +GROUP BY EventDate +ORDER BY EventDate ASC +``` + +``` text +┌──EventDate─┬────ratio─┐ +│ 2014-03-17 │ 1 │ +│ 2014-03-18 │ 0.807696 │ +│ 2014-03-19 │ 0.755406 │ +│ 2014-03-20 │ 0.723218 │ +│ 2014-03-21 │ 0.697021 │ +│ 2014-03-22 │ 0.647851 │ +│ 2014-03-23 │ 0.648416 │ +└────────────┴──────────┘ +``` + +17 Mart'tan sonraki her gün için, 17 Mart'ta siteyi ziyaret eden kullanıcılar tarafından yapılan sayfa görüntüleme yüzdesini Sayın. +IN yan tümcesinde BIR alt sorgu her zaman tek bir sunucuda yalnızca bir kez çalıştırılır. Bağımlı alt sorgular yoktur. + +#### NULL işleme {#null-processing-1} + +İstek işleme sırasında, In operatörü, bir işlemin sonucunun [NULL](../syntax.md) her zaman eşittir `0` olsun ne olursa olsun `NULL` operatörün sağ veya sol tarafındadır. `NULL` değerler herhangi bir veri kümesine dahil edilmez, birbirine karşılık gelmez ve karşılaştırılamaz. + +İşte bir örnek ile `t_null` Tablo: + +``` text +┌─x─┬────y─┐ +│ 1 │ ᴺᵁᴸᴸ │ +│ 2 │ 3 │ +└───┴──────┘ +``` + +Sorguyu çalıştırma `SELECT x FROM t_null WHERE y IN (NULL,3)` size aşağıdaki sonucu verir: + +``` text +┌─x─┐ +│ 2 │ +└───┘ +``` + +Bu satır görebilirsiniz hangi `y = NULL` sorgu sonuçları dışarı atılır. Bunun nedeni ClickHouse karar veremez `NULL` dahildir `(NULL,3)` set, döner `0` operasyon sonucunda ve `SELECT` bu satırı son çıktıdan hariç tutar. + +``` sql +SELECT y IN (NULL, 3) +FROM t_null +``` + +``` text +┌─in(y, tuple(NULL, 3))─┐ +│ 0 │ +│ 1 │ +└───────────────────────┘ +``` + +#### Dağıtılmış Alt Sorgular {#select-distributed-subqueries} + +Alt sorgularla IN-s için iki seçenek vardır (Birleştirmelere benzer): normal `IN` / `JOIN` ve `GLOBAL IN` / `GLOBAL JOIN`. Dağıtılmış sorgu işleme için nasıl çalıştırıldıkları bakımından farklılık gösterirler. + +!!! attention "Dikkat" + Aşağıda açıklanan algoritmaların Aşağıdakilere bağlı olarak farklı şekilde çalışabileceğini unutmayın [ayarlar](../../operations/settings/settings.md) `distributed_product_mode` ayar. + +Normal IN kullanırken, sorgu uzak sunuculara gönderilir ve her biri alt sorguları `IN` veya `JOIN` yan. + +Kullanırken `GLOBAL IN` / `GLOBAL JOINs`, ilk olarak tüm alt sorgular için çalıştırılır `GLOBAL IN` / `GLOBAL JOINs` ve sonuçlar geçici tablolarda toplanır. Daha sonra geçici tablolar, bu geçici verileri kullanarak sorguların çalıştırıldığı her uzak sunucuya gönderilir. + +Dağıtılmış olmayan bir sorgu için normal `IN` / `JOIN`. + +Alt sorguları kullanırken dikkatli olun `IN` / `JOIN` dağıtılmış sorgu işleme için yan tümceleri. + +Bazı örneklere bakalım. Kümedeki her sunucunun normal olduğunu varsayalım **local\_table**. Her sunucu ayrıca bir **distributed\_table** tablo ile **Dağılı** kümedeki tüm sunuculara bakan tür. + +Bir sorgu için **distributed\_table**, sorgu tüm uzak sunuculara gönderilecek ve bunları kullanarak üzerinde çalışacak **local\_table**. + +Örneğin, sorgu + +``` sql +SELECT uniq(UserID) FROM distributed_table +``` + +olarak tüm uzak sunucu sentlara gönder willilecektir + +``` sql +SELECT uniq(UserID) FROM local_table +``` + +ve ara sonuçların birleştirilebileceği aşamaya ulaşana kadar her biri paralel olarak çalıştırın. Daha sonra Ara sonuçlar istekte bulunan sunucuya döndürülür ve üzerinde birleştirilir ve nihai sonuç istemciye gönderilir. + +Şimdi bir sorguyu İN ile inceleyelim: + +``` sql +SELECT uniq(UserID) FROM distributed_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM local_table WHERE CounterID = 34) +``` + +- İki sitenin izleyicilerinin kesişiminin hesaplanması. + +Bu sorgu tüm uzak sunuculara şu şekilde gönderilecektir + +``` sql +SELECT uniq(UserID) FROM local_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM local_table WHERE CounterID = 34) +``` + +Diğer bir deyişle, veri kümesi In yan tümcesi her sunucuda bağımsız olarak, yalnızca yerel olarak her bir sunucu üzerinde depolanan veriler üzerinden toplanır. + +Bu durum için hazırlanan ve tek bir kullanıcı kimliği için veri tamamen tek bir sunucuda bulunduğu küme sunucuları arasında veri yaymak, bu düzgün ve en iyi şekilde çalışır. Bu durumda, gerekli tüm veriler her sunucuda yerel olarak mevcut olacaktır. Aksi takdirde, sonuç yanlış olacaktır. Sorgunun bu varyasyonuna şu şekilde atıfta bulunuyoruz “local IN”. + +Veriler küme sunucularına rastgele yayıldığında sorgunun nasıl çalıştığını düzeltmek için şunları belirtebilirsiniz **distributed\_table** bir alt sorgu içinde. Sorgu şöyle görünürdü: + +``` sql +SELECT uniq(UserID) FROM distributed_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM distributed_table WHERE CounterID = 34) +``` + +Bu sorgu tüm uzak sunuculara şu şekilde gönderilecektir + +``` sql +SELECT uniq(UserID) FROM local_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM distributed_table WHERE CounterID = 34) +``` + +Alt sorgu, her uzak sunucuda çalışmaya başlayacaktır. Alt sorgu dağıtılmış bir tablo kullandığından, her uzak sunucuda bulunan alt sorgu, her uzak sunucuya şu şekilde yeniden gönderilecektir + +``` sql +SELECT UserID FROM local_table WHERE CounterID = 34 +``` + +Örneğin, 100 sunucu kümeniz varsa, tüm sorguyu yürütmek, genellikle kabul edilemez olarak kabul edilen 10.000 temel istek gerektirir. + +Bu gibi durumlarda, her zaman IN yerine GLOBAL IN kullanmalısınız. Sorgu için nasıl çalıştığına bakalım + +``` sql +SELECT uniq(UserID) FROM distributed_table WHERE CounterID = 101500 AND UserID GLOBAL IN (SELECT UserID FROM distributed_table WHERE CounterID = 34) +``` + +Istekçi sunucu alt sorgu çalıştıracaktır + +``` sql +SELECT UserID FROM distributed_table WHERE CounterID = 34 +``` + +ve sonuç RAM'de geçici bir tabloya konacak. Sonra istek olarak her uzak sunucuya gönderilecektir + +``` sql +SELECT uniq(UserID) FROM local_table WHERE CounterID = 101500 AND UserID GLOBAL IN _data1 +``` + +ve geçici tablo `_data1` Sorgu ile her uzak sunucuya gönderilir (geçici tablonun adı uygulama tanımlı). + +Bu normal İN kullanmaktan daha uygun. Ancak, aşağıdaki noktaları aklınızda bulundurun: + +1. Geçici bir tablo oluştururken, veriler benzersiz hale getirilmez. Ağ üzerinden iletilen verilerin hacmini azaltmak için ALT sorguda DISTINCT belirtin. (Bunu normal bir İN için yapmanız gerekmez.) +2. Geçici tablo tüm uzak sunuculara gönderilir. İletim, ağ topolojisini hesaba katmaz. Örneğin, 10 uzak sunucu, istek sahibi sunucuya göre çok uzak bir veri merkezinde bulunuyorsa, veriler uzak veri merkezine kanal üzerinden 10 kez gönderilir. GLOBAL IN kullanırken büyük veri kümelerinden kaçınmaya çalışın. +3. Uzak sunuculara veri iletirken, ağ bant genişliği üzerindeki kısıtlamalar yapılandırılabilir değildir. Şebekeyi aşırı yükleyebilirsiniz. +4. Verileri sunucular arasında dağıtmaya çalışın, böylece GLOBAL IN'Yİ düzenli olarak kullanmanız gerekmez. +5. GLOBAL IN sık sık kullanmanız gerekiyorsa, tek bir yinelemeler grubunun aralarında hızlı bir ağ bulunan birden fazla veri merkezinde bulunmasını sağlamak için ClickHouse kümesinin konumunu planlayın; böylece bir sorgu tamamen tek bir veri merkezi içinde işlenebilir. + +Aynı zamanda yerel bir tablo belirtmek için mantıklı `GLOBAL IN` yan tümcesi, bu yerel tablo yalnızca istek sahibi sunucuda kullanılabilir ve verileri uzak sunucularda kullanmak istediğiniz durumda. + +### Aşırı Değerler {#extreme-values} + +Sonuçlara ek olarak, sonuçlar sütunları için minimum ve maksimum değerleri de alabilirsiniz. Bunu yapmak için, set **çıkmaz** ayar 1. Minimum ve maksimum değerler, sayısal türler, tarihler ve zamanlarla tarihler için hesaplanır. Diğer sütunlar için varsayılan değerler çıktıdır. + +An extra two rows are calculated – the minimums and maximums, respectively. These extra two rows are output in `JSON*`, `TabSeparated*`, ve `Pretty*` [biçimliler](../../interfaces/formats.md), diğer satırlardan ayrı. Diğer formatlar için çıktı değildir. + +İçinde `JSON*` biçimleri, aşırı değerler ayrı bir çıktı ‘extremes’ alan. İçinde `TabSeparated*` formatlar, satır ana sonuçtan sonra gelir ve sonra ‘totals’ varsa. Boş bir satırdan önce gelir (diğer verilerden sonra). İçinde `Pretty*` formatlar, satır ana sonuçtan sonra ayrı bir tablo olarak çıktılanır ve sonra `totals` varsa. + +Aşırı değerler önce satırlar için hesaplanır `LIMIT` ama sonra `LIMIT BY`. Ancak, kullanırken `LIMIT offset, size`, önceki satırlar `offset` dahildir `extremes`. Akış isteklerinde, sonuç, içinden geçen az sayıda satır da içerebilir `LIMIT`. + +### Not {#notes} + +Bu `GROUP BY` ve `ORDER BY` yan tümceleri konumsal bağımsız değişkenleri desteklemez. Bu MySQL ile çelişir, ancak standart SQL ile uyumludur. +Mesela, `GROUP BY 1, 2` will be interpreted as grouping by constants (i.e. aggregation of all rows into one). + +Eşanlamlıları kullanabilirsiniz (`AS` diğer adlar) sorgunun herhangi bir bölümünde. + +Bir ifade yerine bir sorgunun herhangi bir bölümüne Yıldız İşareti koyabilirsiniz. Sorgu analiz edildiğinde, Yıldız İşareti tüm tablo sütunlarının bir listesine genişletilir ( `MATERIALIZED` ve `ALIAS` sütun). Bir yıldız işareti kullanmanın haklı olduğu sadece birkaç durum vardır: + +- Bir tablo dökümü oluştururken. +- Sistem tabloları gibi sadece birkaç sütun içeren tablolar için. +- Bir tabloda hangi sütunların bulunduğu hakkında bilgi almak için. Bu durumda, set `LIMIT 1`. Ama kullanmak daha iyidir `DESC TABLE` sorgu. +- Kullanarak az sayıda sütun üzerinde güçlü filtrasyon olduğunda `PREWHERE`. +- Alt sorgularda (dış sorgu için gerekli olmayan sütunlar alt sorgulardan hariç tutulduğundan). + +Diğer tüm durumlarda, yıldız işaretini kullanmanızı önermiyoruz, çünkü sadece avantajlar yerine sütunlu bir DBMS'NİN dezavantajlarını veriyor. Başka bir deyişle yıldız işaretini kullanmak önerilmez. + +[Orijinal makale](https://clickhouse.tech/docs/en/query_language/select/) diff --git a/docs/zh/sql-reference/statements/select.md b/docs/zh/sql-reference/statements/select.md index 1b1364f23f8..845b4fd4337 100644 --- a/docs/zh/sql-reference/statements/select.md +++ b/docs/zh/sql-reference/statements/select.md @@ -1,59 +1,178 @@ -# SELECT 查询语法 {#select-cha-xun-yu-fa} +--- +machine_translated: true +machine_translated_rev: 0f7ef7704d018700049223525bad4a63911b6e70 +toc_priority: 33 +toc_title: SELECT +--- -`SELECT` 语句用于执行数据的检索。 +# 选择查询语法 {#select-queries-syntax} + +`SELECT` 执行数据检索。 ``` sql +[WITH expr_list|(subquery)] SELECT [DISTINCT] expr_list - [FROM [db.]table | (subquery) | table_function] [FINAL] - [SAMPLE sample_coeff] - [ARRAY JOIN ...] - [GLOBAL] ANY|ALL INNER|LEFT JOIN (subquery)|table USING columns_list - [PREWHERE expr] - [WHERE expr] - [GROUP BY expr_list] [WITH TOTALS] - [HAVING expr] - [ORDER BY expr_list] - [LIMIT n BY columns] - [LIMIT [n, ]m] - [UNION ALL ...] - [INTO OUTFILE filename] - [FORMAT format] +[FROM [db.]table | (subquery) | table_function] [FINAL] +[SAMPLE sample_coeff] +[ARRAY JOIN ...] +[GLOBAL] [ANY|ALL] [INNER|LEFT|RIGHT|FULL|CROSS] [OUTER] JOIN (subquery)|table USING columns_list +[PREWHERE expr] +[WHERE expr] +[GROUP BY expr_list] [WITH TOTALS] +[HAVING expr] +[ORDER BY expr_list] +[LIMIT [offset_value, ]n BY columns] +[LIMIT [n, ]m] +[UNION ALL ...] +[INTO OUTFILE filename] +[FORMAT format] ``` -所有的子句都是可选的,除了SELECT之后的表达式列表(expr\_list)。 -下面将按照查询运行的顺序逐一对各个子句进行说明。 +所有子句都是可选的,除了紧接在SELECT之后的必需表达式列表。 +以下子句的描述顺序几乎与查询执行传送器中的顺序相同。 -如果查询中不包含`DISTINCT`,`GROUP BY`,`ORDER BY`子句以及`IN`和`JOIN`子查询,那么它将仅使用O(1)数量的内存来完全流式的处理查询 -否则,这个查询将消耗大量的内存,除非你指定了这些系统配置:`max_memory_usage`, `max_rows_to_group_by`, `max_rows_to_sort`, `max_rows_in_distinct`, `max_bytes_in_distinct`, `max_rows_in_set`, `max_bytes_in_set`, `max_rows_in_join`, `max_bytes_in_join`, `max_bytes_before_external_sort`, `max_bytes_before_external_group_by`。它们规定了可以使用外部排序(将临时表存储到磁盘中)以及外部聚合,`目前系统不存在关于Join的配置`,更多关于它们的信息,可以参见«配置»部分。 +如果查询省略 `DISTINCT`, `GROUP BY` 和 `ORDER BY` 条款和 `IN` 和 `JOIN` 子查询,查询将被完全流处理,使用O(1)量的RAM。 +否则,如果未指定适当的限制,则查询可能会消耗大量RAM: `max_memory_usage`, `max_rows_to_group_by`, `max_rows_to_sort`, `max_rows_in_distinct`, `max_bytes_in_distinct`, `max_rows_in_set`, `max_bytes_in_set`, `max_rows_in_join`, `max_bytes_in_join`, `max_bytes_before_external_sort`, `max_bytes_before_external_group_by`. 有关详细信息,请参阅部分 “Settings”. 可以使用外部排序(将临时表保存到磁盘)和外部聚合。 `The system does not have "merge join"`. -### FROM 子句 {#select-from} +### WITH条款 {#with-clause} -如果查询中不包含FROM子句,那么将读取`system.one`。 -`system.one`中仅包含一行数据(此表实现了与其他数据库管理系统中的DUAL相同的功能)。 +本节提供对公共表表达式的支持 ([CTE](https://en.wikipedia.org/wiki/Hierarchical_and_recursive_queries_in_SQL)),有一些限制: +1. 不支持递归查询 +2. 当在section中使用子查询时,它的结果应该是只有一行的标量 +3. Expression的结果在子查询中不可用 +WITH子句表达式的结果可以在SELECT子句中使用。 -FROM子句规定了将从哪个表、或子查询、或表函数中读取数据;同时ARRAY JOIN子句和JOIN子句也可以出现在这里(见后文)。 +示例1:使用常量表达式作为 “variable” -可以使用包含在括号里的子查询来替代表。 -在这种情况下,子查询的处理将会构建在外部的查询内部。 -不同于SQL标准,子查询后无需指定别名。为了兼容,你可以在子查询后添加’AS 别名’,但是指定的名字不能被使用在任何地方。 +``` sql +WITH '2019-08-01 15:23:00' as ts_upper_bound +SELECT * +FROM hits +WHERE + EventDate = toDate(ts_upper_bound) AND + EventTime <= ts_upper_bound +``` -也可以使用表函数来代替表,有关信息,参见«表函数»。 +示例2:从SELECT子句列表中逐出sum(bytes)表达式结果 -执行查询时,在查询中列出的所有列都将从对应的表中提取数据;如果你使用的是子查询的方式,则任何在外部查询中没有使用的列,子查询将从查询中忽略它们; -如果你的查询没有列出任何的列(例如,SELECT count() FROM t),则将额外的从表中提取一些列(最好的情况下是最小的列),以便计算行数。 +``` sql +WITH sum(bytes) as s +SELECT + formatReadableSize(s), + table +FROM system.parts +GROUP BY table +ORDER BY s +``` -最后的FINAL修饰符仅能够被使用在SELECT from CollapsingMergeTree场景中。当你为FROM指定了FINAL修饰符时,你的查询结果将会在查询过程中被聚合。需要注意的是,在这种情况下,查询将在单个流中读取所有相关的主键列,同时对需要的数据进行合并。这意味着,当使用FINAL修饰符时,查询将会处理的更慢。在大多数情况下,你应该避免使用FINAL修饰符。更多信息,请参阅«CollapsingMergeTree引擎»部分。 +示例3:使用标量子查询的结果 -### SAMPLE 子句 {#select-sample-clause} +``` sql +/* this example would return TOP 10 of most huge tables */ +WITH + ( + SELECT sum(bytes) + FROM system.parts + WHERE active + ) AS total_disk_usage +SELECT + (sum(bytes) / total_disk_usage) * 100 AS table_disk_usage, + table +FROM system.parts +GROUP BY table +ORDER BY table_disk_usage DESC +LIMIT 10 +``` -通过SAMPLE子句用户可以进行近似查询处理,近似查询处理仅能工作在MergeTree\*类型的表中,并且在创建表时需要您指定采样表达式(参见«MergeTree 引擎»部分)。 +示例4:在子查询中重用表达式 +作为子查询中表达式使用的当前限制的解决方法,您可以复制它。 -`SAMPLE`子句可以使用`SAMPLE k`来表示,其中k可以是0到1的小数值,或者是一个足够大的正整数值。 +``` sql +WITH ['hello'] AS hello +SELECT + hello, + * +FROM +( + WITH ['hello'] AS hello + SELECT hello +) +``` -当k为0到1的小数时,查询将使用’k’作为百分比选取数据。例如,`SAMPLE 0.1`查询只会检索数据总量的10%。 -当k为一个足够大的正整数时,查询将使用’k’作为最大样本数。例如, `SAMPLE 10000000`查询只会检索最多10,000,000行数据。 +``` text +┌─hello─────┬─hello─────┐ +│ ['hello'] │ ['hello'] │ +└───────────┴───────────┘ +``` -示例: +### FROM条款 {#select-from} + +如果FROM子句被省略,数据将从读取 `system.one` 桌子 +该 `system.one` 表只包含一行(此表满足与其他Dbms中找到的双表相同的目的)。 + +该 `FROM` 子句指定从中读取数据的源: + +- 表 +- 子查询 +- [表函数](../table-functions/index.md) + +`ARRAY JOIN` 和常规 `JOIN` 也可以包括在内(见下文)。 + +而不是一个表,该 `SELECT` 子查询可以在括号中指定。 +与标准SQL相比,不需要在子查询后指定同义词。 + +若要执行查询,将从相应的表中提取查询中列出的所有列。 外部查询不需要的任何列都将从子查询中抛出。 +如果查询未列出任何列(例如, `SELECT count() FROM t`),无论如何都会从表中提取一些列(最小的列是首选),以便计算行数。 + +#### 最终修饰符 {#select-from-final} + +从表中选择数据时适用 [MergeTree](../../engines/table-engines/mergetree-family/mergetree.md)-发动机系列比其他 `GraphiteMergeTree`. 当 `FINAL` 如果指定,ClickHouse会在返回结果之前完全合并数据,从而执行给定表引擎合并期间发生的所有数据转换。 + +还支持: +- [复制](../../engines/table-engines/mergetree-family/replication.md) 版本 `MergeTree` 引擎 +- [查看](../../engines/table-engines/special/view.md), [缓冲区](../../engines/table-engines/special/buffer.md), [分布](../../engines/table-engines/special/distributed.md),和 [MaterializedView](../../engines/table-engines/special/materializedview.md) 在其他引擎上运行的引擎,只要它们是在创建 `MergeTree`-发动机表。 + +使用的查询 `FINAL` 执行速度不如类似的查询那么快,因为: + +- 查询在单个线程中执行,并在查询执行期间合并数据。 +- 查询与 `FINAL` 除了读取查询中指定的列之外,还读取主键列。 + +在大多数情况下,避免使用 `FINAL`. + +### 示例子句 {#select-sample-clause} + +该 `SAMPLE` 子句允许近似查询处理。 + +启用数据采样时,不会对所有数据执行查询,而只对特定部分数据(样本)执行查询。 例如,如果您需要计算所有访问的统计信息,只需对所有访问的1/10分数执行查询,然后将结果乘以10即可。 + +近似查询处理在以下情况下可能很有用: + +- 当你有严格的时间requirements(如\<100ms),但你不能证明额外的硬件资源来满足他们的成本。 +- 当您的原始数据不准确时,所以近似不会明显降低质量。 +- 业务需求的目标是近似结果(为了成本效益,或者为了向高级用户推销确切的结果)。 + +!!! note "注" + 您只能使用采样中的表 [MergeTree](../../engines/table-engines/mergetree-family/mergetree.md) 家庭,并且只有在表创建过程中指定了采样表达式(请参阅 [MergeTree引擎](../../engines/table-engines/mergetree-family/mergetree.md#table_engine-mergetree-creating-a-table)). + +下面列出了数据采样的功能: + +- 数据采样是一种确定性机制。 同样的结果 `SELECT .. SAMPLE` 查询始终是相同的。 +- 对于不同的表,采样工作始终如一。 对于具有单个采样键的表,具有相同系数的采样总是选择相同的可能数据子集。 例如,用户Id的示例采用来自不同表的所有可能的用户Id的相同子集的行。 这意味着您可以在子查询中使用示例 [IN](#select-in-operators) 条款 此外,您可以使用 [JOIN](#select-join) 条款 +- 采样允许从磁盘读取更少的数据。 请注意,您必须正确指定采样键。 有关详细信息,请参阅 [创建MergeTree表](../../engines/table-engines/mergetree-family/mergetree.md#table_engine-mergetree-creating-a-table). + +为 `SAMPLE` 子句支持以下语法: + +| SAMPLE Clause Syntax | 产品描述 | +|----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `SAMPLE k` | 这里 `k` 是从0到1的数字。
查询执行于 `k` 数据的分数。 例如, `SAMPLE 0.1` 对10%的数据运行查询。 [碌莽禄more拢more](#select-sample-k) | +| `SAMPLE n` | 这里 `n` 是足够大的整数。
该查询是在至少一个样本上执行的 `n` 行(但不超过这个)。 例如, `SAMPLE 10000000` 在至少10,000,000行上运行查询。 [碌莽禄more拢more](#select-sample-n) | +| `SAMPLE k OFFSET m` | 这里 `k` 和 `m` 是从0到1的数字。
查询在以下示例上执行 `k` 数据的分数。 用于采样的数据由以下偏移 `m` 分数。 [碌莽禄more拢more](#select-sample-offset) | + +#### SAMPLE K {#select-sample-k} + +这里 `k` 从0到1的数字(支持小数和小数表示法)。 例如, `SAMPLE 1/2` 或 `SAMPLE 0.5`. + +在一个 `SAMPLE k` 子句,样品是从 `k` 数据的分数。 示例如下所示: ``` sql SELECT @@ -63,304 +182,455 @@ FROM hits_distributed SAMPLE 0.1 WHERE CounterID = 34 - AND toDate(EventDate) >= toDate('2013-01-29') - AND toDate(EventDate) <= toDate('2013-02-04') - AND NOT DontCountHits - AND NOT Refresh - AND Title != '' GROUP BY Title ORDER BY PageViews DESC LIMIT 1000 ``` -在这个例子中,查询将检索数据总量的0.1 (10%)的数据。值得注意的是,查询不会自动校正聚合函数最终的结果,所以为了得到更加精确的结果,需要将`count()`的结果手动乘以10。 +在此示例中,对0.1(10%)数据的样本执行查询。 聚合函数的值不会自动修正,因此要获得近似结果,值 `count()` 手动乘以10。 -当使用像`SAMPLE 10000000`这样的方式进行近似查询时,由于没有了任何关于将会处理了哪些数据或聚合函数应该被乘以几的信息,所以这种方式不适合在这种场景下使用。 +#### SAMPLE N {#select-sample-n} -使用相同的采样率得到的结果总是一致的:如果我们能够看到所有可能存在在表中的数据,那么相同的采样率总是能够得到相同的结果(在建表时使用相同的采样表达式),换句话说,系统在不同的时间,不同的服务器,不同表上总以相同的方式对数据进行采样。 +这里 `n` 是足够大的整数。 例如, `SAMPLE 10000000`. -例如,我们可以使用采样的方式获取到与不进行采样相同的用户ID的列表。这将表明,你可以在IN子查询中使用采样,或者使用采样的结果与其他查询进行关联。 +在这种情况下,查询在至少一个样本上执行 `n` 行(但不超过这个)。 例如, `SAMPLE 10000000` 在至少10,000,000行上运行查询。 -### ARRAY JOIN 子句 {#select-array-join-clause} +由于数据读取的最小单位是一个颗粒(其大小由 `index_granularity` 设置),是有意义的设置一个样品,其大小远大于颗粒。 -ARRAY JOIN子句可以帮助查询进行与数组和nested数据类型的连接。它有点类似arrayJoin函数,但它的功能更广泛。 +使用时 `SAMPLE n` 子句,你不知道处理了哪些数据的相对百分比。 所以你不知道聚合函数应该乘以的系数。 使用 `_sample_factor` 虚拟列得到近似结果。 -`ARRAY JOIN` 本质上等同于`INNERT JOIN`数组。 例如: +该 `_sample_factor` 列包含动态计算的相对系数。 当您执行以下操作时,将自动创建此列 [创建](../../engines/table-engines/mergetree-family/mergetree.md#table_engine-mergetree-creating-a-table) 具有指定采样键的表。 的使用示例 `_sample_factor` 列如下所示。 - :) CREATE TABLE arrays_test (s String, arr Array(UInt8)) ENGINE = Memory +让我们考虑表 `visits`,其中包含有关网站访问的统计信息。 第一个示例演示如何计算页面浏览量: - CREATE TABLE arrays_test - ( - s String, - arr Array(UInt8) - ) ENGINE = Memory +``` sql +SELECT sum(PageViews * _sample_factor) +FROM visits +SAMPLE 10000000 +``` - Ok. +下一个示例演示如何计算访问总数: - 0 rows in set. Elapsed: 0.001 sec. +``` sql +SELECT sum(_sample_factor) +FROM visits +SAMPLE 10000000 +``` - :) INSERT INTO arrays_test VALUES ('Hello', [1,2]), ('World', [3,4,5]), ('Goodbye', []) +下面的示例显示了如何计算平均会话持续时间。 请注意,您不需要使用相对系数来计算平均值。 - INSERT INTO arrays_test VALUES +``` sql +SELECT avg(Duration) +FROM visits +SAMPLE 10000000 +``` - Ok. +#### SAMPLE K OFFSET M {#select-sample-offset} - 3 rows in set. Elapsed: 0.001 sec. +这里 `k` 和 `m` 是从0到1的数字。 示例如下所示。 - :) SELECT * FROM arrays_test +**示例1** - SELECT * - FROM arrays_test +``` sql +SAMPLE 1/10 +``` - ┌─s───────┬─arr─────┐ - │ Hello │ [1,2] │ - │ World │ [3,4,5] │ - │ Goodbye │ [] │ - └─────────┴─────────┘ +在此示例中,示例是所有数据的十分之一: - 3 rows in set. Elapsed: 0.001 sec. +`[++------------]` - :) SELECT s, arr FROM arrays_test ARRAY JOIN arr +**示例2** - SELECT s, arr - FROM arrays_test - ARRAY JOIN arr +``` sql +SAMPLE 1/10 OFFSET 1/2 +``` - ┌─s─────┬─arr─┐ - │ Hello │ 1 │ - │ Hello │ 2 │ - │ World │ 3 │ - │ World │ 4 │ - │ World │ 5 │ - └───────┴─────┘ +这里,从数据的后半部分取出10%的样本。 - 5 rows in set. Elapsed: 0.001 sec. +`[------++------]` -你还可以为ARRAY JOIN子句指定一个别名,这时你可以通过这个别名来访问数组中的数据,但是数据本身仍然可以通过原来的名称进行访问。例如: +### ARRAY JOIN子句 {#select-array-join-clause} - :) SELECT s, arr, a FROM arrays_test ARRAY JOIN arr AS a - - SELECT s, arr, a - FROM arrays_test - ARRAY JOIN arr AS a - - ┌─s─────┬─arr─────┬─a─┐ - │ Hello │ [1,2] │ 1 │ - │ Hello │ [1,2] │ 2 │ - │ World │ [3,4,5] │ 3 │ - │ World │ [3,4,5] │ 4 │ - │ World │ [3,4,5] │ 5 │ - └───────┴─────────┴───┘ - - 5 rows in set. Elapsed: 0.001 sec. - -当多个具有相同大小的数组使用逗号分割出现在ARRAY JOIN子句中时,ARRAY JOIN会将它们同时执行(直接合并,而不是它们的笛卡尔积)。例如: - - :) SELECT s, arr, a, num, mapped FROM arrays_test ARRAY JOIN arr AS a, arrayEnumerate(arr) AS num, arrayMap(x -> x + 1, arr) AS mapped - - SELECT s, arr, a, num, mapped - FROM arrays_test - ARRAY JOIN arr AS a, arrayEnumerate(arr) AS num, arrayMap(lambda(tuple(x), plus(x, 1)), arr) AS mapped - - ┌─s─────┬─arr─────┬─a─┬─num─┬─mapped─┐ - │ Hello │ [1,2] │ 1 │ 1 │ 2 │ - │ Hello │ [1,2] │ 2 │ 2 │ 3 │ - │ World │ [3,4,5] │ 3 │ 1 │ 4 │ - │ World │ [3,4,5] │ 4 │ 2 │ 5 │ - │ World │ [3,4,5] │ 5 │ 3 │ 6 │ - └───────┴─────────┴───┴─────┴────────┘ - - 5 rows in set. Elapsed: 0.002 sec. - - :) SELECT s, arr, a, num, arrayEnumerate(arr) FROM arrays_test ARRAY JOIN arr AS a, arrayEnumerate(arr) AS num - - SELECT s, arr, a, num, arrayEnumerate(arr) - FROM arrays_test - ARRAY JOIN arr AS a, arrayEnumerate(arr) AS num - - ┌─s─────┬─arr─────┬─a─┬─num─┬─arrayEnumerate(arr)─┐ - │ Hello │ [1,2] │ 1 │ 1 │ [1,2] │ - │ Hello │ [1,2] │ 2 │ 2 │ [1,2] │ - │ World │ [3,4,5] │ 3 │ 1 │ [1,2,3] │ - │ World │ [3,4,5] │ 4 │ 2 │ [1,2,3] │ - │ World │ [3,4,5] │ 5 │ 3 │ [1,2,3] │ - └───────┴─────────┴───┴─────┴─────────────────────┘ - - 5 rows in set. Elapsed: 0.002 sec. - -另外ARRAY JOIN也可以工作在nested数据结构上。例如: - - :) CREATE TABLE nested_test (s String, nest Nested(x UInt8, y UInt32)) ENGINE = Memory - - CREATE TABLE nested_test - ( - s String, - nest Nested( - x UInt8, - y UInt32) - ) ENGINE = Memory - - Ok. - - 0 rows in set. Elapsed: 0.006 sec. - - :) INSERT INTO nested_test VALUES ('Hello', [1,2], [10,20]), ('World', [3,4,5], [30,40,50]), ('Goodbye', [], []) - - INSERT INTO nested_test VALUES - - Ok. - - 3 rows in set. Elapsed: 0.001 sec. - - :) SELECT * FROM nested_test - - SELECT * - FROM nested_test - - ┌─s───────┬─nest.x──┬─nest.y─────┐ - │ Hello │ [1,2] │ [10,20] │ - │ World │ [3,4,5] │ [30,40,50] │ - │ Goodbye │ [] │ [] │ - └─────────┴─────────┴────────────┘ - - 3 rows in set. Elapsed: 0.001 sec. - - :) SELECT s, nest.x, nest.y FROM nested_test ARRAY JOIN nest - - SELECT s, `nest.x`, `nest.y` - FROM nested_test - ARRAY JOIN nest - - ┌─s─────┬─nest.x─┬─nest.y─┐ - │ Hello │ 1 │ 10 │ - │ Hello │ 2 │ 20 │ - │ World │ 3 │ 30 │ - │ World │ 4 │ 40 │ - │ World │ 5 │ 50 │ - └───────┴────────┴────────┘ - - 5 rows in set. Elapsed: 0.001 sec. - -当你在ARRAY JOIN指定nested数据类型的名称时,其作用与与包含所有数组元素的ARRAY JOIN相同,例如: - - :) SELECT s, nest.x, nest.y FROM nested_test ARRAY JOIN nest.x, nest.y - - SELECT s, `nest.x`, `nest.y` - FROM nested_test - ARRAY JOIN `nest.x`, `nest.y` - - ┌─s─────┬─nest.x─┬─nest.y─┐ - │ Hello │ 1 │ 10 │ - │ Hello │ 2 │ 20 │ - │ World │ 3 │ 30 │ - │ World │ 4 │ 40 │ - │ World │ 5 │ 50 │ - └───────┴────────┴────────┘ - - 5 rows in set. Elapsed: 0.001 sec. - -这种方式也是可以运行的: - - :) SELECT s, nest.x, nest.y FROM nested_test ARRAY JOIN nest.x - - SELECT s, `nest.x`, `nest.y` - FROM nested_test - ARRAY JOIN `nest.x` - - ┌─s─────┬─nest.x─┬─nest.y─────┐ - │ Hello │ 1 │ [10,20] │ - │ Hello │ 2 │ [10,20] │ - │ World │ 3 │ [30,40,50] │ - │ World │ 4 │ [30,40,50] │ - │ World │ 5 │ [30,40,50] │ - └───────┴────────┴────────────┘ - - 5 rows in set. Elapsed: 0.001 sec. - -为了方便使用原来的nested类型的数组,你可以为nested类型定义一个别名。例如: - - :) SELECT s, n.x, n.y, nest.x, nest.y FROM nested_test ARRAY JOIN nest AS n - - SELECT s, `n.x`, `n.y`, `nest.x`, `nest.y` - FROM nested_test - ARRAY JOIN nest AS n - - ┌─s─────┬─n.x─┬─n.y─┬─nest.x──┬─nest.y─────┐ - │ Hello │ 1 │ 10 │ [1,2] │ [10,20] │ - │ Hello │ 2 │ 20 │ [1,2] │ [10,20] │ - │ World │ 3 │ 30 │ [3,4,5] │ [30,40,50] │ - │ World │ 4 │ 40 │ [3,4,5] │ [30,40,50] │ - │ World │ 5 │ 50 │ [3,4,5] │ [30,40,50] │ - └───────┴─────┴─────┴─────────┴────────────┘ - - 5 rows in set. Elapsed: 0.001 sec. - -使用arrayEnumerate函数的示例: - - :) SELECT s, n.x, n.y, nest.x, nest.y, num FROM nested_test ARRAY JOIN nest AS n, arrayEnumerate(nest.x) AS num - - SELECT s, `n.x`, `n.y`, `nest.x`, `nest.y`, num - FROM nested_test - ARRAY JOIN nest AS n, arrayEnumerate(`nest.x`) AS num - - ┌─s─────┬─n.x─┬─n.y─┬─nest.x──┬─nest.y─────┬─num─┐ - │ Hello │ 1 │ 10 │ [1,2] │ [10,20] │ 1 │ - │ Hello │ 2 │ 20 │ [1,2] │ [10,20] │ 2 │ - │ World │ 3 │ 30 │ [3,4,5] │ [30,40,50] │ 1 │ - │ World │ 4 │ 40 │ [3,4,5] │ [30,40,50] │ 2 │ - │ World │ 5 │ 50 │ [3,4,5] │ [30,40,50] │ 3 │ - └───────┴─────┴─────┴─────────┴────────────┴─────┘ - - 5 rows in set. Elapsed: 0.002 sec. - -在一个查询中只能出现一个ARRAY JOIN子句。 - -如果在WHERE/PREWHERE子句中使用了ARRAY JOIN子句的结果,它将优先于WHERE/PREWHERE子句执行,否则它将在WHERE/PRWHERE子句之后执行,以便减少计算。 - -### JOIN 子句 {#select-join} - -JOIN子句用于连接数据,作用与[SQL JOIN](https://en.wikipedia.org/wiki/Join_(SQL))的定义相同。 - -!!! info "注意" - 与 [ARRAY JOIN](#select-array-join-clause) 没有关系. +允许执行 `JOIN` 具有数组或嵌套数据结构。 意图类似于 [arrayJoin](../functions/array-join.md#functions_arrayjoin) 功能,但其功能更广泛。 ``` sql SELECT FROM -[GLOBAL] [ANY|ALL] INNER|LEFT|RIGHT|FULL|CROSS [OUTER] JOIN +[LEFT] ARRAY JOIN +[WHERE|PREWHERE ] +... +``` + +您只能指定一个 `ARRAY JOIN` 查询中的子句。 + +运行时优化查询执行顺序 `ARRAY JOIN`. 虽然 `ARRAY JOIN` 必须始终之前指定 `WHERE/PREWHERE` 子句,它可以执行之前 `WHERE/PREWHERE` (如果结果是需要在这个子句),或完成后(以减少计算量)。 处理顺序由查询优化器控制。 + +支持的类型 `ARRAY JOIN` 下面列出: + +- `ARRAY JOIN` -在这种情况下,空数组不包括在结果中 `JOIN`. +- `LEFT ARRAY JOIN` -的结果 `JOIN` 包含具有空数组的行。 空数组的值设置为数组元素类型的默认值(通常为0、空字符串或NULL)。 + +下面的例子演示的用法 `ARRAY JOIN` 和 `LEFT ARRAY JOIN` 条款 让我们创建一个表 [阵列](../../sql-reference/data-types/array.md) 键入column并在其中插入值: + +``` sql +CREATE TABLE arrays_test +( + s String, + arr Array(UInt8) +) ENGINE = Memory; + +INSERT INTO arrays_test +VALUES ('Hello', [1,2]), ('World', [3,4,5]), ('Goodbye', []); +``` + +``` text +┌─s───────────┬─arr─────┐ +│ Hello │ [1,2] │ +│ World │ [3,4,5] │ +│ Goodbye │ [] │ +└─────────────┴─────────┘ +``` + +下面的例子使用 `ARRAY JOIN` 条款: + +``` sql +SELECT s, arr +FROM arrays_test +ARRAY JOIN arr; +``` + +``` text +┌─s─────┬─arr─┐ +│ Hello │ 1 │ +│ Hello │ 2 │ +│ World │ 3 │ +│ World │ 4 │ +│ World │ 5 │ +└───────┴─────┘ +``` + +下一个示例使用 `LEFT ARRAY JOIN` 条款: + +``` sql +SELECT s, arr +FROM arrays_test +LEFT ARRAY JOIN arr; +``` + +``` text +┌─s───────────┬─arr─┐ +│ Hello │ 1 │ +│ Hello │ 2 │ +│ World │ 3 │ +│ World │ 4 │ +│ World │ 5 │ +│ Goodbye │ 0 │ +└─────────────┴─────┘ +``` + +#### 使用别名 {#using-aliases} + +可以为数组中的别名指定 `ARRAY JOIN` 条款 在这种情况下,数组项目可以通过此别名访问,但数组本身可以通过原始名称访问。 示例: + +``` sql +SELECT s, arr, a +FROM arrays_test +ARRAY JOIN arr AS a; +``` + +``` text +┌─s─────┬─arr─────┬─a─┐ +│ Hello │ [1,2] │ 1 │ +│ Hello │ [1,2] │ 2 │ +│ World │ [3,4,5] │ 3 │ +│ World │ [3,4,5] │ 4 │ +│ World │ [3,4,5] │ 5 │ +└───────┴─────────┴───┘ +``` + +使用别名,您可以执行 `ARRAY JOIN` 与外部阵列。 例如: + +``` sql +SELECT s, arr_external +FROM arrays_test +ARRAY JOIN [1, 2, 3] AS arr_external; +``` + +``` text +┌─s───────────┬─arr_external─┐ +│ Hello │ 1 │ +│ Hello │ 2 │ +│ Hello │ 3 │ +│ World │ 1 │ +│ World │ 2 │ +│ World │ 3 │ +│ Goodbye │ 1 │ +│ Goodbye │ 2 │ +│ Goodbye │ 3 │ +└─────────────┴──────────────┘ +``` + +多个数组可以在逗号分隔 `ARRAY JOIN` 条款 在这种情况下, `JOIN` 与它们同时执行(直接和,而不是笛卡尔积)。 请注意,所有数组必须具有相同的大小。 示例: + +``` sql +SELECT s, arr, a, num, mapped +FROM arrays_test +ARRAY JOIN arr AS a, arrayEnumerate(arr) AS num, arrayMap(x -> x + 1, arr) AS mapped; +``` + +``` text +┌─s─────┬─arr─────┬─a─┬─num─┬─mapped─┐ +│ Hello │ [1,2] │ 1 │ 1 │ 2 │ +│ Hello │ [1,2] │ 2 │ 2 │ 3 │ +│ World │ [3,4,5] │ 3 │ 1 │ 4 │ +│ World │ [3,4,5] │ 4 │ 2 │ 5 │ +│ World │ [3,4,5] │ 5 │ 3 │ 6 │ +└───────┴─────────┴───┴─────┴────────┘ +``` + +下面的例子使用 [arrayEnumerate](../../sql-reference/functions/array-functions.md#array_functions-arrayenumerate) 功能: + +``` sql +SELECT s, arr, a, num, arrayEnumerate(arr) +FROM arrays_test +ARRAY JOIN arr AS a, arrayEnumerate(arr) AS num; +``` + +``` text +┌─s─────┬─arr─────┬─a─┬─num─┬─arrayEnumerate(arr)─┐ +│ Hello │ [1,2] │ 1 │ 1 │ [1,2] │ +│ Hello │ [1,2] │ 2 │ 2 │ [1,2] │ +│ World │ [3,4,5] │ 3 │ 1 │ [1,2,3] │ +│ World │ [3,4,5] │ 4 │ 2 │ [1,2,3] │ +│ World │ [3,4,5] │ 5 │ 3 │ [1,2,3] │ +└───────┴─────────┴───┴─────┴─────────────────────┘ +``` + +#### 具有嵌套数据结构的数组连接 {#array-join-with-nested-data-structure} + +`ARRAY`加入"也适用于 [嵌套数据结构](../../sql-reference/data-types/nested-data-structures/nested.md). 示例: + +``` sql +CREATE TABLE nested_test +( + s String, + nest Nested( + x UInt8, + y UInt32) +) ENGINE = Memory; + +INSERT INTO nested_test +VALUES ('Hello', [1,2], [10,20]), ('World', [3,4,5], [30,40,50]), ('Goodbye', [], []); +``` + +``` text +┌─s───────┬─nest.x──┬─nest.y─────┐ +│ Hello │ [1,2] │ [10,20] │ +│ World │ [3,4,5] │ [30,40,50] │ +│ Goodbye │ [] │ [] │ +└─────────┴─────────┴────────────┘ +``` + +``` sql +SELECT s, `nest.x`, `nest.y` +FROM nested_test +ARRAY JOIN nest; +``` + +``` text +┌─s─────┬─nest.x─┬─nest.y─┐ +│ Hello │ 1 │ 10 │ +│ Hello │ 2 │ 20 │ +│ World │ 3 │ 30 │ +│ World │ 4 │ 40 │ +│ World │ 5 │ 50 │ +└───────┴────────┴────────┘ +``` + +当指定嵌套数据结构的名称 `ARRAY JOIN`,意思是一样的 `ARRAY JOIN` 它包含的所有数组元素。 下面列出了示例: + +``` sql +SELECT s, `nest.x`, `nest.y` +FROM nested_test +ARRAY JOIN `nest.x`, `nest.y`; +``` + +``` text +┌─s─────┬─nest.x─┬─nest.y─┐ +│ Hello │ 1 │ 10 │ +│ Hello │ 2 │ 20 │ +│ World │ 3 │ 30 │ +│ World │ 4 │ 40 │ +│ World │ 5 │ 50 │ +└───────┴────────┴────────┘ +``` + +这种变化也是有道理的: + +``` sql +SELECT s, `nest.x`, `nest.y` +FROM nested_test +ARRAY JOIN `nest.x`; +``` + +``` text +┌─s─────┬─nest.x─┬─nest.y─────┐ +│ Hello │ 1 │ [10,20] │ +│ Hello │ 2 │ [10,20] │ +│ World │ 3 │ [30,40,50] │ +│ World │ 4 │ [30,40,50] │ +│ World │ 5 │ [30,40,50] │ +└───────┴────────┴────────────┘ +``` + +可以将别名用于嵌套数据结构,以便选择 `JOIN` 结果或源数组。 示例: + +``` sql +SELECT s, `n.x`, `n.y`, `nest.x`, `nest.y` +FROM nested_test +ARRAY JOIN nest AS n; +``` + +``` text +┌─s─────┬─n.x─┬─n.y─┬─nest.x──┬─nest.y─────┐ +│ Hello │ 1 │ 10 │ [1,2] │ [10,20] │ +│ Hello │ 2 │ 20 │ [1,2] │ [10,20] │ +│ World │ 3 │ 30 │ [3,4,5] │ [30,40,50] │ +│ World │ 4 │ 40 │ [3,4,5] │ [30,40,50] │ +│ World │ 5 │ 50 │ [3,4,5] │ [30,40,50] │ +└───────┴─────┴─────┴─────────┴────────────┘ +``` + +使用的例子 [arrayEnumerate](../../sql-reference/functions/array-functions.md#array_functions-arrayenumerate) 功能: + +``` sql +SELECT s, `n.x`, `n.y`, `nest.x`, `nest.y`, num +FROM nested_test +ARRAY JOIN nest AS n, arrayEnumerate(`nest.x`) AS num; +``` + +``` text +┌─s─────┬─n.x─┬─n.y─┬─nest.x──┬─nest.y─────┬─num─┐ +│ Hello │ 1 │ 10 │ [1,2] │ [10,20] │ 1 │ +│ Hello │ 2 │ 20 │ [1,2] │ [10,20] │ 2 │ +│ World │ 3 │ 30 │ [3,4,5] │ [30,40,50] │ 1 │ +│ World │ 4 │ 40 │ [3,4,5] │ [30,40,50] │ 2 │ +│ World │ 5 │ 50 │ [3,4,5] │ [30,40,50] │ 3 │ +└───────┴─────┴─────┴─────────┴────────────┴─────┘ +``` + +### JOIN子句 {#select-join} + +加入正常的数据 [SQL JOIN](https://en.wikipedia.org/wiki/Join_(SQL)) 感觉 + +!!! info "注" + 不相关的 [ARRAY JOIN](#select-array-join-clause). + +``` sql +SELECT +FROM +[GLOBAL] [ANY|ALL] [INNER|LEFT|RIGHT|FULL|CROSS] [OUTER] JOIN (ON )|(USING ) ... ``` -可以使用具体的表名来代替``与``。但这与使用`SELECT * FROM table`子查询的方式相同。除非你的表是\[Join\](../operations/table\_engines/join.md -**支持的`JOIN`类型** +可以指定表名,而不是 `` 和 ``. 这相当于 `SELECT * FROM table` 子查询,除了在特殊情况下,当表具有 [加入我们](../../engines/table-engines/special/join.md) engine – an array prepared for joining. -- `INNER JOIN` -- `LEFT OUTER JOIN` -- `RIGHT OUTER JOIN` -- `FULL OUTER JOIN` -- `CROSS JOIN` +#### 支持的类型 `JOIN` {#select-join-types} -你可以跳过默认的`OUTER`关键字。 +- `INNER JOIN` (或 `JOIN`) +- `LEFT JOIN` (或 `LEFT OUTER JOIN`) +- `RIGHT JOIN` (或 `RIGHT OUTER JOIN`) +- `FULL JOIN` (或 `FULL OUTER JOIN`) +- `CROSS JOIN` (或 `,` ) -**`ANY` 与 `ALL`** +查看标准 [SQL JOIN](https://en.wikipedia.org/wiki/Join_(SQL)) 描述。 -在使用`ALL`修饰符对JOIN进行修饰时,如果右表中存在多个与左表关联的数据,那么系统则将右表中所有可以与左表关联的数据全部返回在结果中。这与SQL标准的JOIN行为相同。 -在使用`ANY`修饰符对JOIN进行修饰时,如果右表中存在多个与左表关联的数据,那么系统仅返回第一个与左表匹配的结果。如果左表与右表一一对应,不存在多余的行时,`ANY`与`ALL`的结果相同。 +#### 多联接 {#multiple-join} -你可以在会话中通过设置 [join\_default\_strictness](../../operations/settings/settings.md) 来指定默认的JOIN修饰符。 +执行查询时,ClickHouse将多表联接重写为双表联接的序列。 例如,如果有四个连接表ClickHouse连接第一个和第二个,然后将结果与第三个表连接,并在最后一步,它连接第四个表。 -**`GLOBAL` 分布** +如果查询包含 `WHERE` 子句,ClickHouse尝试通过中间联接从此子句推下过滤器。 如果无法将筛选器应用于每个中间联接,ClickHouse将在所有联接完成后应用筛选器。 -当使用普通的`JOIN`时,查询将被发送给远程的服务器。并在这些远程服务器上生成右表并与它们关联。换句话说,右表来自于各个服务器本身。 +我们建议 `JOIN ON` 或 `JOIN USING` 用于创建查询的语法。 例如: -当使用`GLOBAL ... JOIN`,首先会在请求服务器上计算右表并以临时表的方式将其发送到所有服务器。这时每台服务器将直接使用它进行计算。 +``` sql +SELECT * FROM t1 JOIN t2 ON t1.a = t2.a JOIN t3 ON t1.a = t3.a +``` -使用`GLOBAL`时需要小心。更多信息,参阅 [分布式子查询](#select-distributed-subqueries) 部分。 +您可以使用逗号分隔的列表中的表 `FROM` 条款 例如: -**使用建议** +``` sql +SELECT * FROM t1, t2, t3 WHERE t1.a = t2.a AND t1.a = t3.a +``` -从子查询中删除所有`JOIN`不需要的列。 +不要混合使用这些语法。 -当执行`JOIN`查询时,因为与其他阶段相比没有进行执行顺序的优化:JOIN优先于WHERE与聚合执行。因此,为了显示的指定执行顺序,我们推荐你使用子查询的方式执行`JOIN`。 +ClickHouse不直接支持使用逗号的语法,所以我们不建议使用它们。 该算法尝试重写查询 `CROSS JOIN` 和 `INNER JOIN` 子句,然后继续进行查询处理。 重写查询时,ClickHouse会尝试优化性能和内存消耗。 默认情况下,ClickHouse将逗号视为 `INNER JOIN` 子句和转换 `INNER JOIN` 到 `CROSS JOIN` 当算法不能保证 `INNER JOIN` 返回所需的数据。 + +#### 严格 {#select-join-strictness} + +- `ALL` — If the right table has several matching rows, ClickHouse creates a [笛卡尔积](https://en.wikipedia.org/wiki/Cartesian_product) 从匹配的行。 这是标准 `JOIN` SQL中的行为。 +- `ANY` — If the right table has several matching rows, only the first one found is joined. If the right table has only one matching row, the results of queries with `ANY` 和 `ALL` 关键字是相同的。 +- `ASOF` — For joining sequences with a non-exact match. `ASOF JOIN` 用法描述如下。 + +**ASOF加入使用** + +`ASOF JOIN` 当您需要连接没有完全匹配的记录时非常有用。 + +表 `ASOF JOIN` 必须具有有序序列列。 此列不能单独存在于表中,并且应该是其中一种数据类型: `UInt32`, `UInt64`, `Float32`, `Float64`, `Date`,和 `DateTime`. + +语法 `ASOF JOIN ... ON`: + +``` sql +SELECT expressions_list +FROM table_1 +ASOF LEFT JOIN table_2 +ON equi_cond AND closest_match_cond +``` + +您可以使用任意数量的相等条件和恰好一个最接近的匹配条件。 例如, `SELECT count() FROM table_1 ASOF LEFT JOIN table_2 ON table_1.a == table_2.b AND table_2.t <= table_1.t`. + +支持最接近匹配的条件: `>`, `>=`, `<`, `<=`. + +语法 `ASOF JOIN ... USING`: + +``` sql +SELECT expressions_list +FROM table_1 +ASOF JOIN table_2 +USING (equi_column1, ... equi_columnN, asof_column) +``` + +`ASOF JOIN` 用途 `equi_columnX` 对于加入平等和 `asof_column` 用于加入与最接近的比赛 `table_1.asof_column >= table_2.asof_column` 条件。 该 `asof_column` 列总是在最后一个 `USING` 条款 + +例如,请考虑下表: + + table_1 table_2 + event | ev_time | user_id event | ev_time | user_id + ----------|---------|---------- ----------|---------|---------- + ... ... + event_1_1 | 12:00 | 42 event_2_1 | 11:59 | 42 + ... event_2_2 | 12:30 | 42 + event_1_2 | 13:00 | 42 event_2_3 | 13:00 | 42 + ... ... + +`ASOF JOIN` 可以从用户事件的时间戳 `table_1` 并找到一个事件 `table_2` 其中时间戳最接近事件的时间戳 `table_1` 对应于最接近的匹配条件。 如果可用,则相等的时间戳值是最接近的值。 在这里,该 `user_id` 列可用于连接相等和 `ev_time` 列可用于在最接近的匹配加入。 在我们的例子中, `event_1_1` 可以加入 `event_2_1` 和 `event_1_2` 可以加入 `event_2_3`,但是 `event_2_2` 不能加入。 + +!!! note "注" + `ASOF` 加入是 **不** 支持在 [加入我们](../../engines/table-engines/special/join.md) 表引擎。 + +若要设置默认严格性值,请使用session configuration参数 [join\_default\_strictness](../../operations/settings/settings.md#settings-join_default_strictness). + +#### GLOBAL JOIN {#global-join} + +当使用正常 `JOIN`,将查询发送到远程服务器。 为了创建正确的表,在每个子查询上运行子查询,并使用此表执行联接。 换句话说,在每个服务器上单独形成右表。 + +使用时 `GLOBAL ... JOIN`,首先请求者服务器运行一个子查询来计算正确的表。 此临时表将传递到每个远程服务器,并使用传输的临时数据对其运行查询。 + +使用时要小心 `GLOBAL`. 有关详细信息,请参阅部分 [分布式子查询](#select-distributed-subqueries). + +#### 使用建议 {#usage-recommendations} + +当运行 `JOIN`,与查询的其他阶段相关的执行顺序没有优化。 连接(在右表中搜索)在过滤之前运行 `WHERE` 和聚集之前。 为了明确设置处理顺序,我们建议运行 `JOIN` 具有子查询的子查询。 示例: @@ -388,72 +658,91 @@ ORDER BY hits DESC LIMIT 10 ``` - ┌─CounterID─┬───hits─┬─visits─┐ - │ 1143050 │ 523264 │ 13665 │ - │ 731962 │ 475698 │ 102716 │ - │ 722545 │ 337212 │ 108187 │ - │ 722889 │ 252197 │ 10547 │ - │ 2237260 │ 196036 │ 9522 │ - │ 23057320 │ 147211 │ 7689 │ - │ 722818 │ 90109 │ 17847 │ - │ 48221 │ 85379 │ 4652 │ - │ 19762435 │ 77807 │ 7026 │ - │ 722884 │ 77492 │ 11056 │ - └───────────┴────────┴────────┘ +``` text +┌─CounterID─┬───hits─┬─visits─┐ +│ 1143050 │ 523264 │ 13665 │ +│ 731962 │ 475698 │ 102716 │ +│ 722545 │ 337212 │ 108187 │ +│ 722889 │ 252197 │ 10547 │ +│ 2237260 │ 196036 │ 9522 │ +│ 23057320 │ 147211 │ 7689 │ +│ 722818 │ 90109 │ 17847 │ +│ 48221 │ 85379 │ 4652 │ +│ 19762435 │ 77807 │ 7026 │ +│ 722884 │ 77492 │ 11056 │ +└───────────┴────────┴────────┘ +``` -子查询不允许您设置别名或在其他地方引用它们。 -`USING`中指定的列必须在两个子查询中具有相同的名称,而其他列必须具有不同的名称。您可以通过使用别名的方式来更改子查询中的列名(示例中就分别使用了’hits’与’visits’别名)。 +子查询不允许您设置名称或使用它们从特定子查询引用列。 +在指定的列 `USING` 两个子查询中必须具有相同的名称,并且其他列必须以不同的方式命名。 您可以使用别名更改子查询中的列名(此示例使用别名 `hits` 和 `visits`). -`USING`子句用于指定要进行链接的一个或多个列,系统会将这些列在两张表中相等的值连接起来。如果列是一个列表,不需要使用括号包裹。同时JOIN不支持其他更复杂的Join方式。 +该 `USING` 子句指定一个或多个要联接的列,这将建立这些列的相等性。 列的列表设置不带括号。 不支持更复杂的连接条件。 -右表(子查询的结果)将会保存在内存中。如果没有足够的内存,则无法运行`JOIN`。 +正确的表(子查询结果)驻留在RAM中。 如果没有足够的内存,则无法运行 `JOIN`. -只能在查询中指定一个`JOIN`。若要运行多个`JOIN`,你可以将它们放入子查询中。 +每次使用相同的查询运行 `JOIN`,子查询再次运行,因为结果未缓存。 为了避免这种情况,使用特殊的 [加入我们](../../engines/table-engines/special/join.md) 表引擎,它是一个用于连接的准备好的数组,总是在RAM中。 -每次运行相同的`JOIN`查询,总是会再次计算 - 没有缓存结果。 为了避免这种情况,可以使用’Join’引擎,它是一个预处理的Join数据结构,总是保存在内存中。更多信息,参见«Join引擎»部分。 +在某些情况下,使用效率更高 `IN` 而不是 `JOIN`. +在各种类型的 `JOIN`,最有效的是 `ANY LEFT JOIN`,然后 `ANY INNER JOIN`. 效率最低的是 `ALL LEFT JOIN` 和 `ALL INNER JOIN`. -在一些场景下,使用`IN`代替`JOIN`将会得到更高的效率。在各种类型的JOIN中,最高效的是`ANY LEFT JOIN`,然后是`ANY INNER JOIN`,效率最差的是`ALL LEFT JOIN`以及`ALL INNER JOIN`。 +如果你需要一个 `JOIN` 对于连接维度表(这些是包含维度属性的相对较小的表,例如广告活动的名称), `JOIN` 由于每个查询都会重新访问正确的表,因此可能不太方便。 对于这种情况下,有一个 “external dictionaries” 您应该使用的功能 `JOIN`. 有关详细信息,请参阅部分 [外部字典](../dictionaries/external-dictionaries/external-dicts.md). -如果你需要使用`JOIN`来关联一些纬度表(包含纬度属性的一些相对比较小的表,例如广告活动的名称),那么`JOIN`可能不是好的选择,因为语法负责,并且每次查询都将重新访问这些表。对于这种情况,您应该使用«外部字典»的功能来替换`JOIN`。更多信息,参见 [外部字典](../../sql-reference/statements/select.md) 部分。 +**内存限制** -#### Null的处理 {#nullde-chu-li} +ClickHouse使用 [哈希联接](https://en.wikipedia.org/wiki/Hash_join) 算法。 ClickHouse采取 `` 并在RAM中为其创建哈希表。 如果需要限制联接操作内存消耗,请使用以下设置: -JOIN的行为受 [join\_use\_nulls](../../operations/settings/settings.md) 的影响。当`join_use_nulls=1`时,`JOIN`的工作与SQL标准相同。 +- [max\_rows\_in\_join](../../operations/settings/query-complexity.md#settings-max_rows_in_join) — Limits number of rows in the hash table. +- [max\_bytes\_in\_join](../../operations/settings/query-complexity.md#settings-max_bytes_in_join) — Limits size of the hash table. -如果JOIN的key是 [可为空](../../sql-reference/statements/select.md) 类型的字段,则其中至少一个存在 [NULL](../syntax.md#null-literal) 值的key不会被关联。 +当任何这些限制达到,ClickHouse作为 [join\_overflow\_mode](../../operations/settings/query-complexity.md#settings-join_overflow_mode) 设置指示。 -### WHERE 子句 {#select-where} +#### 处理空单元格或空单元格 {#processing-of-empty-or-null-cells} -如果存在WHERE子句, 则在该子句中必须包含一个UInt8类型的表达式。 这个表达是通常是一个带有比较和逻辑的表达式。 -这个表达式将会在所有数据转换前用来过滤数据。 +在连接表时,可能会出现空单元格。 设置 [join\_use\_nulls](../../operations/settings/settings.md#join_use_nulls) 定义ClickHouse如何填充这些单元格。 -如果在支持索引的数据库表引擎中,这个表达式将被评估是否使用索引。 +如果 `JOIN` 键是 [可为空](../data-types/nullable.md) 字段,其中至少有一个键具有值的行 [NULL](../syntax.md#null-literal) 没有加入。 -### PREWHERE 子句 {#prewhere-zi-ju} +#### 语法限制 {#syntax-limitations} -这个子句与WHERE子句的意思相同。主要的不同之处在于表数据的读取。 -当使用PREWHERE时,首先只读取PREWHERE表达式中需要的列。然后在根据PREWHERE执行的结果读取其他需要的列。 +对于多个 `JOIN` 单个子句 `SELECT` 查询: -如果在过滤条件中有少量不适合索引过滤的列,但是它们又可以提供很强的过滤能力。这时使用PREWHERE是有意义的,因为它将帮助减少数据的读取。 +- 通过以所有列 `*` 仅在联接表时才可用,而不是子查询。 +- 该 `PREWHERE` 条款不可用。 -例如,在一个需要提取大量列的查询中为少部分列编写PREWHERE是很有作用的。 +为 `ON`, `WHERE`,和 `GROUP BY` 条款: -PREWHERE 仅支持`*MergeTree`系列引擎。 +- 任意表达式不能用于 `ON`, `WHERE`,和 `GROUP BY` 子句,但你可以定义一个表达式 `SELECT` 子句,然后通过别名在这些子句中使用它。 -在一个查询中可以同时指定PREWHERE和WHERE,在这种情况下,PREWHERE优先于WHERE执行。 +### WHERE条款 {#select-where} -值得注意的是,PREWHERE不适合用于已经存在于索引中的列,因为当列已经存在于索引中的情况下,只有满足索引的数据块才会被读取。 +如果存在WHERE子句,则必须包含具有UInt8类型的表达式。 这通常是一个带有比较和逻辑运算符的表达式。 +此表达式将用于在所有其他转换之前过滤数据。 -如果将’optimize\_move\_to\_prewhere’设置为1,并且在查询中不包含PREWHERE,则系统将自动的把适合PREWHERE表达式的部分从WHERE中抽离到PREWHERE中。 +如果数据库表引擎支持索引,则根据使用索引的能力计算表达式。 -### GROUP BY 子句 {#select-group-by-clause} +### PREWHERE条款 {#prewhere-clause} -这是列式数据库管理系统中最重要的一部分。 +此条款与WHERE条款具有相同的含义。 区别在于从表中读取数据。 +使用PREWHERE时,首先只读取执行PREWHERE所需的列。 然后读取运行查询所需的其他列,但只读取PREWHERE表达式为true的那些块。 -如果存在GROUP BY子句,则在该子句中必须包含一个表达式列表。其中每个表达式将会被称之为«key»。 -SELECT,HAVING,ORDER BY子句中的表达式列表必须来自于这些«key»或聚合函数。简而言之,被选择的列中不能包含非聚合函数或key之外的其他列。 +如果查询中的少数列使用过滤条件,但提供强大的数据过滤,则使用PREWHERE是有意义的。 这减少了要读取的数据量。 -如果查询表达式列表中仅包含聚合函数,则可以省略GROUP BY子句,这时会假定将所有数据聚合成一组空«key»。 +例如,对于提取大量列但仅对少数列进行过滤的查询,编写PREWHERE非常有用。 + +PREWHERE仅由来自 `*MergeTree` 家人 + +查询可以同时指定PREWHERE和WHERE。 在这种情况下,PREWHERE先于WHERE。 + +如果 ‘optimize\_move\_to\_prewhere’ 设置设置为1并省略PREWHERE,系统使用启发式方法自动将部分表达式从哪里移动到哪里。 + +### GROUP BY子句 {#select-group-by-clause} + +这是面向列的DBMS最重要的部分之一。 + +如果存在GROUP BY子句,则必须包含表达式列表。 每个表达式将在这里被称为 “key”. +SELECT、HAVING和ORDER BY子句中的所有表达式都必须从键或聚合函数计算。 换句话说,从表中选择的每个列必须在键或聚合函数内使用。 + +如果查询仅包含聚合函数中的表列,则可以省略GROUP BY子句,并假定通过一组空键进行聚合。 示例: @@ -465,9 +754,9 @@ SELECT FROM hits ``` -与SQL标准不同的是,如果表中不存在任何数据(可能表本身中就不存在任何数据,或者由于被WHERE条件过滤掉了),将返回一个空结果,而不是一个包含聚合函数初始值的结果。 +但是,与标准SQL相比,如果表没有任何行(根本没有任何行,或者在使用WHERE to filter之后没有任何行),则返回一个空结果,而不是来自包含聚合函数初始值的行之 -与MySQL不同的是(实际上这是符合SQL标准的),你不能够获得一个不在key中的非聚合函数列(除了常量表达式)。但是你可以使用’any’(返回遇到的第一个值)、max、min等聚合函数使它工作。 +相对于MySQL(并且符合标准SQL),您无法获取不在键或聚合函数(常量表达式除外)中的某些列的某些值。 要解决此问题,您可以使用 ‘any’ 聚合函数(获取第一个遇到的值)或 ‘min/max’. 示例: @@ -480,88 +769,138 @@ FROM hits GROUP BY domain ``` -GROUP BY子句会为遇到的每一个不同的key计算一组聚合函数的值。 +对于遇到的每个不同的键值,GROUP BY计算一组聚合函数值。 -在GROUP BY子句中不支持使用Array类型的列。 +数组列不支持分组依据。 -常量不能作为聚合函数的参数传入聚合函数中。例如: sum(1)。这种情况下你可以省略常量。例如:`count()`。 +不能将常量指定为聚合函数的参数。 示例:sum(1)。 相反,你可以摆脱常数。 示例: `count()`. -#### NULL 处理 {#null-chu-li} +#### 空处理 {#null-processing} 对于GROUP BY子句,ClickHouse将 [NULL](../syntax.md#null-literal) 解释为一个值,并且支持`NULL=NULL`。 -下面这个例子将说明这将意味着什么。 +这里有一个例子来说明这意味着什么。 -假设你有这样一张表: +假设你有这张桌子: - ┌─x─┬────y─┐ - │ 1 │ 2 │ - │ 2 │ ᴺᵁᴸᴸ │ - │ 3 │ 2 │ - │ 3 │ 3 │ - │ 3 │ ᴺᵁᴸᴸ │ - └───┴──────┘ +``` text +┌─x─┬────y─┐ +│ 1 │ 2 │ +│ 2 │ ᴺᵁᴸᴸ │ +│ 3 │ 2 │ +│ 3 │ 3 │ +│ 3 │ ᴺᵁᴸᴸ │ +└───┴──────┘ +``` -运行`SELECT sum(x), y FROM t_null_big GROUP BY y`你将得到如下结果: +查询 `SELECT sum(x), y FROM t_null_big GROUP BY y` 结果: - ┌─sum(x)─┬────y─┐ - │ 4 │ 2 │ - │ 3 │ 3 │ - │ 5 │ ᴺᵁᴸᴸ │ - └────────┴──────┘ +``` text +┌─sum(x)─┬────y─┐ +│ 4 │ 2 │ +│ 3 │ 3 │ +│ 5 │ ᴺᵁᴸᴸ │ +└────────┴──────┘ +``` -你可以看到GROUP BY为`y=NULL`的聚合了x。 +你可以看到 `GROUP BY` 为 `y = NULL` 总结 `x`,仿佛 `NULL` 是这个值。 -如果你在向`GROUP BY`中放入几个key,结果将列出所有的组合可能。就像`NULL`是一个特定的值一样。 +如果你通过几个键 `GROUP BY`,结果会给你选择的所有组合,就好像 `NULL` 是一个特定的值。 -#### WITH TOTALS 修饰符 {#with-totals-xiu-shi-fu} +#### 使用总计修饰符 {#with-totals-modifier} -如果你指定了WITH TOTALS修饰符,你将会在结果中得到一个被额外计算出的行。在这一行中将包含所有key的默认值(零或者空值),以及所有聚合函数对所有被选择数据行的聚合结果。 +如果指定了WITH TOTALS修饰符,则将计算另一行。 此行将具有包含默认值(零或空行)的关键列,以及包含跨所有行计算值的聚合函数列( “total” 值)。 -该行仅在JSON\*, TabSeparated\*, Pretty\*输出格式中与其他行分开输出。 +这个额外的行以JSON\*,TabSeparated\*和Pretty\*格式输出,与其他行分开。 在其他格式中,此行不输出。 -在JSON\*输出格式中,这行将出现在Json的’totals’字段中。在TabSeparated\*输出格式中,这行将位于其他结果之后,同时与其他结果使用空白行分隔。在Pretty\*输出格式中,这行将作为单独的表在所有结果之后输出。 +在JSON\*格式中,此行作为单独的输出 ‘totals’ 场。 在TabSeparated\*格式中,该行位于主结果之后,前面有一个空行(在其他数据之后)。 在Pretty\*格式中,该行在主结果之后作为单独的表输出。 -当`WITH TOTALS`与HAVING子句同时存在时,它的行为受’totals\_mode’配置的影响。 -默认情况下,`totals_mode = 'before_having'`,这时`WITH TOTALS`将会在HAVING前计算最多不超过`max_rows_to_group_by`行的数据。 +`WITH TOTALS` 当有存在时,可以以不同的方式运行。 该行为取决于 ‘totals\_mode’ 设置。 +默认情况下, `totals_mode = 'before_having'`. 在这种情况下, ‘totals’ 是跨所有行计算,包括那些不通过具有和 ‘max\_rows\_to\_group\_by’. -在`group_by_overflow_mode = 'any'`并指定了`max_rows_to_group_by`的情况下,`WITH TOTALS`的行为受`totals_mode`的影响。 +其他替代方案仅包括通过具有在 ‘totals’,并与设置不同的行为 `max_rows_to_group_by` 和 `group_by_overflow_mode = 'any'`. -`after_having_exclusive` - 在HAVING后进行计算,计算不超过`max_rows_to_group_by`行的数据。 +`after_having_exclusive` – Don't include rows that didn't pass through `max_rows_to_group_by`. 换句话说, ‘totals’ 将有少于或相同数量的行,因为它会 `max_rows_to_group_by` 被省略。 -`after_having_inclusive` - 在HAVING后进行计算,计算不少于`max_rows_to_group_by`行的数据。 +`after_having_inclusive` – Include all the rows that didn't pass through ‘max\_rows\_to\_group\_by’ 在 ‘totals’. 换句话说, ‘totals’ 将有多个或相同数量的行,因为它会 `max_rows_to_group_by` 被省略。 -`after_having_auto` - 在HAVING后进行计算,采用统计通过HAVING的行数,在超过不超过’max\_rows\_to\_group\_by’指定值(默认为50%)的情况下,包含所有行的结果。否则排除这些结果。 +`after_having_auto` – Count the number of rows that passed through HAVING. If it is more than a certain amount (by default, 50%), include all the rows that didn't pass through ‘max\_rows\_to\_group\_by’ 在 ‘totals’. 否则,不包括它们。 -`totals_auto_threshold` - 默认 0.5,是`after_having_auto`的参数。 +`totals_auto_threshold` – By default, 0.5. The coefficient for `after_having_auto`. -如果`group_by_overflow_mode != 'any'`并没有指定`max_rows_to_group_by`情况下,所有的模式都与`after_having`相同。 +如果 `max_rows_to_group_by` 和 `group_by_overflow_mode = 'any'` 不使用,所有的变化 `after_having` 是相同的,你可以使用它们中的任何一个(例如, `after_having_auto`). -你可以在子查询,包含子查询的JOIN子句中使用WITH TOTALS(在这种情况下,它们各自的总值会被组合在一起)。 +您可以在子查询中使用总计,包括在JOIN子句中的子查询(在这种情况下,将合并各自的总计值)。 -#### GROUP BY 使用外部存储设备 {#select-group-by-in-external-memory} +#### 在外部存储器中分组 {#select-group-by-in-external-memory} -你可以在GROUP BY中允许将临时数据转存到磁盘上,以限制对内存的使用。 -`max_bytes_before_external_group_by`这个配置确定了在GROUP BY中启动将临时数据转存到磁盘上的内存阈值。如果你将它设置为0(这是默认值),这项功能将被禁用。 +您可以启用将临时数据转储到磁盘以限制内存使用期间 `GROUP BY`. +该 [max\_bytes\_before\_external\_group\_by](../../operations/settings/settings.md#settings-max_bytes_before_external_group_by) 设置确定倾销的阈值RAM消耗 `GROUP BY` 临时数据到文件系统。 如果设置为0(默认值),它将被禁用。 -当使用`max_bytes_before_external_group_by`时,我们建议将max\_memory\_usage设置为它的两倍。这是因为一个聚合需要两个阶段来完成:(1)读取数据并形成中间数据 (2)合并中间数据。临时数据的转存只会发生在第一个阶段。如果没有发生临时文件的转存,那么阶段二将最多消耗与1阶段相同的内存大小。 +使用时 `max_bytes_before_external_group_by`,我们建议您设置 `max_memory_usage` 大约两倍高。 这是必要的,因为聚合有两个阶段:读取日期和形成中间数据(1)和合并中间数据(2)。 将数据转储到文件系统只能在阶段1中发生。 如果未转储临时数据,则阶段2可能需要与阶段1相同的内存量。 -例如:如果将`max_memory_usage`设置为10000000000并且你想要开启外部聚合,那么你需要将`max_bytes_before_external_group_by`设置为10000000000的同时将`max_memory_usage`设置为20000000000。当外部聚合被触发时(如果刚好只形成了一份临时数据),它的内存使用量将会稍高与`max_bytes_before_external_group_by`。 +例如,如果 [max\_memory\_usage](../../operations/settings/settings.md#settings_max_memory_usage) 设置为10000000000,你想使用外部聚合,这是有意义的设置 `max_bytes_before_external_group_by` 到10000000000,max\_memory\_usage到20000000000。 当触发外部聚合(如果至少有一个临时数据转储)时,RAM的最大消耗仅略高于 `max_bytes_before_external_group_by`. -在分布式查询处理中,外部聚合将会在远程的服务器中执行。为了使请求服务器只使用较少的内存,可以设置`distributed_aggregation_memory_efficient`为1。 +通过分布式查询处理,在远程服务器上执行外部聚合。 为了使请求者服务器只使用少量的RAM,设置 `distributed_aggregation_memory_efficient` 到1。 -当合并被刷到磁盘的临时数据以及合并远程的服务器返回的结果时,如果在启动`distributed_aggregation_memory_efficient`的情况下,将会消耗1/256 \* 线程数的总内存大小。 +当合并数据刷新到磁盘时,以及当合并来自远程服务器的结果时, `distributed_aggregation_memory_efficient` 设置被启用,消耗高达 `1/256 * the_number_of_threads` 从RAM的总量。 -当启动外部聚合时,如果数据的大小小于`max_bytes_before_external_group_by`设置的值(数据没有被刷到磁盘中),那么数据的聚合速度将会和没有启动外部聚合时一样快。如果有临时数据被刷到了磁盘中,那么这个查询的运行时间将会被延长几倍(大约是3倍)。 +当启用外部聚合时,如果有小于 `max_bytes_before_external_group_by` of data (i.e. data was not flushed), the query runs just as fast as without external aggregation. If any temporary data was flushed, the run time will be several times longer (approximately three times). -如果你在GROUP BY后面存在ORDER BY子句,并且ORDER BY后面存在一个极小限制的LIMIT,那么ORDER BY子句将不会使用太多内存。 -否则请不要忘记启动外部排序(`max_bytes_before_external_sort`)。 +如果你有一个 `ORDER BY` 用一个 `LIMIT` 后 `GROUP BY`,然后使用的RAM的量取决于数据的量 `LIMIT`,不是在整个表。 但如果 `ORDER BY` 没有 `LIMIT`,不要忘记启用外部排序 (`max_bytes_before_external_sort`). -### LIMIT N BY 子句 {#limit-n-by-zi-ju} +### 限制条款 {#limit-by-clause} -LIMIT N BY子句和LIMIT没有关系, LIMIT N BY COLUMNS 子句可以用来在每一个COLUMNS分组中求得最大的N行数据。我们可以将它们同时用在一个查询中。LIMIT N BY子句中可以包含任意多个分组字段表达式列表。 +与查询 `LIMIT n BY expressions` 子句选择第一个 `n` 每个不同值的行 `expressions`. 的关键 `LIMIT BY` 可以包含任意数量的 [表达式](../syntax.md#syntax-expressions). -示例: +ClickHouse支持以下语法: + +- `LIMIT [offset_value, ]n BY expressions` +- `LIMIT n OFFSET offset_value BY expressions` + +在查询处理过程中,ClickHouse会选择按排序键排序的数据。 排序键使用以下命令显式设置 [ORDER BY](#select-order-by) 子句或隐式作为表引擎的属性。 然后ClickHouse应用 `LIMIT n BY expressions` 并返回第一 `n` 每个不同组合的行 `expressions`. 如果 `OFFSET` 被指定,则对于每个数据块属于一个不同的组合 `expressions`,ClickHouse跳过 `offset_value` 从块开始的行数,并返回最大值 `n` 行的结果。 如果 `offset_value` 如果数据块中的行数大于数据块中的行数,ClickHouse将从该块返回零行。 + +`LIMIT BY` 是不相关的 `LIMIT`. 它们都可以在同一个查询中使用。 + +**例** + +样品表: + +``` sql +CREATE TABLE limit_by(id Int, val Int) ENGINE = Memory; +INSERT INTO limit_by values(1, 10), (1, 11), (1, 12), (2, 20), (2, 21); +``` + +查询: + +``` sql +SELECT * FROM limit_by ORDER BY id, val LIMIT 2 BY id +``` + +``` text +┌─id─┬─val─┐ +│ 1 │ 10 │ +│ 1 │ 11 │ +│ 2 │ 20 │ +│ 2 │ 21 │ +└────┴─────┘ +``` + +``` sql +SELECT * FROM limit_by ORDER BY id, val LIMIT 1, 2 BY id +``` + +``` text +┌─id─┬─val─┐ +│ 1 │ 11 │ +│ 1 │ 12 │ +│ 2 │ 21 │ +└────┴─────┘ +``` + +该 `SELECT * FROM limit_by ORDER BY id, val LIMIT 2 OFFSET 1 BY id` 查询返回相同的结果。 + +以下查询返回每个引用的前5个引用 `domain, device_type` 最多可与100行配对 (`LIMIT n BY + LIMIT`). ``` sql SELECT @@ -576,105 +915,201 @@ LIMIT 5 BY domain, device_type LIMIT 100 ``` -查询将会为每个`domain, device_type`的组合选出前5个访问最多的数据,但是结果最多将不超过100行(`LIMIT n BY + LIMIT`)。 +### 有条款 {#having-clause} -### HAVING 子句 {#having-zi-ju} +允许筛选GROUP BY之后收到的结果,类似于WHERE子句。 +WHERE和HAVING的不同之处在于WHERE是在聚合(GROUP BY)之前执行的,而HAVING是在聚合之后执行的。 +如果不执行聚合,则不能使用HAVING。 -HAVING子句可以用来过滤GROUP BY之后的数据,类似于WHERE子句。 -WHERE于HAVING不同之处在于WHERE在聚合前(GROUP BY)执行,HAVING在聚合后执行。 -如果不存在聚合,则不能使用HAVING。 +### 按条款订购 {#select-order-by} -### ORDER BY 子句 {#select-order-by} +ORDER BY子句包含一个表达式列表,每个表达式都可以分配DESC或ASC(排序方向)。 如果未指定方向,则假定ASC。 ASC按升序排序,DESC按降序排序。 排序方向适用于单个表达式,而不适用于整个列表。 示例: `ORDER BY Visits DESC, SearchPhrase` -如果存在ORDER BY 子句,则该子句中必须存在一个表达式列表,表达式列表中每一个表达式都可以分配一个DESC或ASC(排序的方向)。如果没有指明排序的方向,将假定以ASC的方式进行排序。其中ASC表示按照升序排序,DESC按照降序排序。示例:`ORDER BY Visits DESC, SearchPhrase` +对于按字符串值排序,可以指定排序规则(比较)。 示例: `ORDER BY SearchPhrase COLLATE 'tr'` -对于按关键字升序排序,使用土耳其字母,不区分大小写,假设字符串是UTF-8编码。 COLLATE可以按顺序独立地为每个表达式指定或不指定。 如果指定了ASC或DESC,则在其后指定COLLATE。 使用COLLATE时,排序始终不区分大小写。 -对于字符串的排序来讲,你可以为其指定一个排序规则,在指定排序规则时,排序总是不会区分大小写。并且如果与ASC或DESC同时出现时,排序规则必须在它们的后面指定。例如:`ORDER BY SearchPhrase COLLATE 'tr'` - 使用土耳其字母表对它进行升序排序,同时排序时不会区分大小写,并按照UTF-8字符集进行编码。 +我们只建议使用COLLATE对少量行进行最终排序,因为使用COLLATE进行排序的效率低于正常按字节进行排序的效率。 -我们推荐只在少量的数据集中使用COLLATE,因为COLLATE的效率远低于正常的字节排序。 +对于排序表达式列表具有相同值的行,将以任意顺序输出,也可以是不确定的(每次都不同)。 +如果省略ORDER BY子句,则行的顺序也是未定义的,并且可能也是不确定的。 -针对排序表达式中相同值的行将以任意的顺序进行输出,这是不确定的(每次都可能不同)。 -如果省略ORDER BY子句,则结果的顺序也是不固定的。 +`NaN` 和 `NULL` 排序顺序: -`NaN` 和 `NULL` 的排序规则: - -- 当使用`NULLS FIRST`修饰符时,将会先输出`NULL`,然后是`NaN`,最后才是其他值。 -- 当使用`NULLS LAST`修饰符时,将会先输出其他值,然后是`NaN`,最后才是`NULL`。 -- 默认情况下与使用`NULLS LAST`修饰符相同。 +- 使用修饰符 `NULLS FIRST` — First `NULL`,然后 `NaN`,然后其他值。 +- 使用修饰符 `NULLS LAST` — First the values, then `NaN`,然后 `NULL`. +- Default — The same as with the `NULLS LAST` 修饰符。 示例: -假设存在如下一张表 +对于表 - ┌─x─┬────y─┐ - │ 1 │ ᴺᵁᴸᴸ │ - │ 2 │ 2 │ - │ 1 │ nan │ - │ 2 │ 2 │ - │ 3 │ 4 │ - │ 5 │ 6 │ - │ 6 │ nan │ - │ 7 │ ᴺᵁᴸᴸ │ - │ 6 │ 7 │ - │ 8 │ 9 │ - └───┴──────┘ +``` text +┌─x─┬────y─┐ +│ 1 │ ᴺᵁᴸᴸ │ +│ 2 │ 2 │ +│ 1 │ nan │ +│ 2 │ 2 │ +│ 3 │ 4 │ +│ 5 │ 6 │ +│ 6 │ nan │ +│ 7 │ ᴺᵁᴸᴸ │ +│ 6 │ 7 │ +│ 8 │ 9 │ +└───┴──────┘ +``` -运行查询 `SELECT * FROM t_null_nan ORDER BY y NULLS FIRST` 将获得如下结果: +运行查询 `SELECT * FROM t_null_nan ORDER BY y NULLS FIRST` 获得: - ┌─x─┬────y─┐ - │ 1 │ ᴺᵁᴸᴸ │ - │ 7 │ ᴺᵁᴸᴸ │ - │ 1 │ nan │ - │ 6 │ nan │ - │ 2 │ 2 │ - │ 2 │ 2 │ - │ 3 │ 4 │ - │ 5 │ 6 │ - │ 6 │ 7 │ - │ 8 │ 9 │ - └───┴──────┘ +``` text +┌─x─┬────y─┐ +│ 1 │ ᴺᵁᴸᴸ │ +│ 7 │ ᴺᵁᴸᴸ │ +│ 1 │ nan │ +│ 6 │ nan │ +│ 2 │ 2 │ +│ 2 │ 2 │ +│ 3 │ 4 │ +│ 5 │ 6 │ +│ 6 │ 7 │ +│ 8 │ 9 │ +└───┴──────┘ +``` -当使用浮点类型的数值进行排序时,不管排序的顺序如何,NaNs总是出现在所有值的后面。换句话说,当你使用升序排列一个浮点数值列时,NaNs好像比所有值都要大。反之,当你使用降序排列一个浮点数值列时,NaNs好像比所有值都小。 +当对浮点数进行排序时,Nan与其他值是分开的。 无论排序顺序如何,Nan都在最后。 换句话说,对于升序排序,它们被放置为好像它们比所有其他数字大,而对于降序排序,它们被放置为好像它们比其他数字小。 -如果你在ORDER BY子句后面存在LIMIT并给定了较小的数值,则将会使用较少的内存。否则,内存的使用量将与需要排序的数据成正比。对于分布式查询,如果省略了GROUP BY,则在远程服务器上执行部分排序,最后在请求服务器上合并排序结果。这意味这对于分布式查询而言,要排序的数据量可以大于单台服务器的内存。 +如果除了ORDER BY之外指定了足够小的限制,则使用较少的RAM。 否则,所花费的内存量与用于排序的数据量成正比。 对于分布式查询处理,如果省略GROUP BY,则在远程服务器上部分完成排序,并在请求者服务器上合并结果。 这意味着对于分布式排序,要排序的数据量可以大于单个服务器上的内存量。 -如果没有足够的内存,可以使用外部排序(在磁盘中创建一些临时文件)。可以使用`max_bytes_before_external_sort`来设置外部排序,如果你讲它设置为0(默认),则表示禁用外部排序功能。如果启用该功能。当要排序的数据量达到所指定的字节数时,当前排序的结果会被转存到一个临时文件中去。当全部数据读取完毕后,所有的临时文件将会合并成最终输出结果。这些临时文件将会写到config文件配置的/var/lib/clickhouse/tmp/目录中(默认值,你可以通过修改’tmp\_path’配置调整该目录的位置)。 +如果没有足够的RAM,则可以在外部存储器中执行排序(在磁盘上创建临时文件)。 使用设置 `max_bytes_before_external_sort` 为此目的。 如果将其设置为0(默认值),则禁用外部排序。 如果启用,则当要排序的数据量达到指定的字节数时,将对收集的数据进行排序并转储到临时文件中。 读取所有数据后,将合并所有已排序的文件并输出结果。 文件被写入配置中的/var/lib/clickhouse/tmp/目录(默认情况下,但您可以使用 ‘tmp\_path’ 参数来更改此设置)。 -查询运行使用的内存要高于’max\_bytes\_before\_external\_sort’,为此,这个配置必须要远远小于’max\_memory\_usage’配置的值。例如,如果你的服务器有128GB的内存去运行一个查询,那么推荐你将’max\_memory\_usage’设置为100GB,’max\_bytes\_before\_external\_sort’设置为80GB。 +运行查询可能占用的内存比 ‘max\_bytes\_before\_external\_sort’. 因此,此设置的值必须大大小于 ‘max\_memory\_usage’. 例如,如果您的服务器有128GB的RAM,并且您需要运行单个查询,请设置 ‘max\_memory\_usage’ 到100GB,和 ‘max\_bytes\_before\_external\_sort’ 至80GB。 -外部排序效率要远低于在内存中排序。 +外部排序的工作效率远远低于在RAM中进行排序。 -### SELECT 子句 {#select-zi-ju} +### SELECT子句 {#select-select} -在完成上述列出的所有子句后,将对SELECT子句中的表达式进行分析。 -具体来讲,如果在存在聚合函数的情况下,将对聚合函数之前的表达式进行分析。 -聚合函数与聚合函数之前的表达式都将在聚合期间完成计算(GROUP BY)。 -就像他们本身就已经存在结果上一样。 +[表达式](../syntax.md#syntax-expressions) 在指定 `SELECT` 子句是在上述子句中的所有操作完成后计算的。 这些表达式的工作方式就好像它们应用于结果中的单独行一样。 如果在表达式 `SELECT` 子句包含聚合函数,然后ClickHouse处理过程中用作其参数的聚合函数和表达式 [GROUP BY](#select-group-by-clause) 聚合。 -### DISTINCT 子句 {#select-distinct} +如果要在结果中包含所有列,请使用星号 (`*`)符号。 例如, `SELECT * FROM ...`. -如果存在DISTINCT子句,则会对结果中的完全相同的行进行去重。 -在GROUP BY不包含聚合函数,并对全部SELECT部分都包含在GROUP BY中时的作用一样。但该子句还是与GROUP BY子句存在以下几点不同: +将结果中的某些列与 [re2](https://en.wikipedia.org/wiki/RE2_(software)) 正则表达式,您可以使用 `COLUMNS` 表达。 -- 可以与GROUP BY配合使用。 -- 当不存在ORDER BY子句并存在LIMIT子句时,查询将在同时满足DISTINCT与LIMIT的情况下立即停止查询。 -- 在处理数据的同时输出结果,并不是等待整个查询全部完成。 +``` sql +COLUMNS('regexp') +``` -在SELECT表达式中存在Array类型的列时,不能使用DISTINCT。 +例如,考虑表: + +``` sql +CREATE TABLE default.col_names (aa Int8, ab Int8, bc Int8) ENGINE = TinyLog +``` + +以下查询从包含以下内容的所有列中选择数据 `a` 在他们的名字符号。 + +``` sql +SELECT COLUMNS('a') FROM col_names +``` + +``` text +┌─aa─┬─ab─┐ +│ 1 │ 1 │ +└────┴────┘ +``` + +所选列不按字母顺序返回。 + +您可以使用多个 `COLUMNS` 查询中的表达式并将函数应用于它们。 + +例如: + +``` sql +SELECT COLUMNS('a'), COLUMNS('c'), toTypeName(COLUMNS('c')) FROM col_names +``` + +``` text +┌─aa─┬─ab─┬─bc─┬─toTypeName(bc)─┐ +│ 1 │ 1 │ 1 │ Int8 │ +└────┴────┴────┴────────────────┘ +``` + +由返回的每一列 `COLUMNS` 表达式作为单独的参数传递给函数。 如果函数支持其他参数,您也可以将其他参数传递给函数。 使用函数时要小心。 如果函数不支持您传递给它的参数数,ClickHouse将引发异常。 + +例如: + +``` sql +SELECT COLUMNS('a') + COLUMNS('c') FROM col_names +``` + +``` text +Received exception from server (version 19.14.1): +Code: 42. DB::Exception: Received from localhost:9000. DB::Exception: Number of arguments for function plus doesn't match: passed 3, should be 2. +``` + +在这个例子中, `COLUMNS('a')` 返回两列: `aa` 和 `ab`. `COLUMNS('c')` 返回 `bc` 列。 该 `+` 运算符不能应用于3个参数,因此ClickHouse引发一个带有相关消息的异常。 + +匹配的列 `COLUMNS` 表达式可以具有不同的数据类型。 如果 `COLUMNS` 不匹配任何列,并且是唯一的表达式 `SELECT`,ClickHouse抛出异常。 + +### DISTINCT子句 {#select-distinct} + +如果指定了DISTINCT,则在结果中所有完全匹配的行集中,只有一行将保留。 +结果将与在没有聚合函数的情况下在SELECT中指定的所有字段中指定GROUP BY一样。 但有几个区别,从组通过: + +- DISTINCT可以与GROUP BY一起应用。 +- 如果省略ORDER BY并定义LIMIT,则在读取所需数量的不同行后,查询立即停止运行。 +- 数据块在处理时输出,而无需等待整个查询完成运行。 + +如果SELECT至少有一个数组列,则不支持DISTINCT。 + +`DISTINCT` 适用于 [NULL](../syntax.md) 就好像 `NULL` 是一个特定的值,并且 `NULL=NULL`. 换句话说,在 `DISTINCT` 结果,不同的组合 `NULL` 只发生一次。 + +ClickHouse支持使用 `DISTINCT` 和 `ORDER BY` 一个查询中不同列的子句。 该 `DISTINCT` 子句之前执行 `ORDER BY` 条款 + +示例表: + +``` text +┌─a─┬─b─┐ +│ 2 │ 1 │ +│ 1 │ 2 │ +│ 3 │ 3 │ +│ 2 │ 4 │ +└───┴───┘ +``` `DISTINCT`可以与 [NULL](../syntax.md#null-literal)一起工作,就好像`NULL`仅是一个特殊的值一样,并且`NULL=NULL`。换而言之,在`DISTINCT`的结果中,与`NULL`不同的组合仅能出现一次。 -### LIMIT 子句 {#limit-zi-ju} +``` text +┌─a─┐ +│ 2 │ +│ 1 │ +│ 3 │ +└───┘ +``` -LIMIT m 用于在查询结果中选择前m行数据。 -LIMIT n, m 用于在查询结果中选择从n行开始的m行数据。 +如果我们改变排序方向 `SELECT DISTINCT a FROM t1 ORDER BY b DESC`,我们得到以下结果: -’n’与’m’必须是正整数。 +``` text +┌─a─┐ +│ 3 │ +│ 1 │ +│ 2 │ +└───┘ +``` -如果没有指定ORDER BY子句,则结果可能是任意的顺序,并且是不确定的。 +行 `2, 4` 分拣前被切割。 -### UNION ALL 子句 {#union-all-zi-ju} +在编程查询时考虑这种实现特异性。 -UNION ALL子句可以组合任意数量的查询,例如: +### 限制条款 {#limit-clause} + +`LIMIT m` 允许您选择第一个 `m` 结果中的行。 + +`LIMIT n, m` 允许您选择第一个 `m` 跳过第一个结果后的行 `n` 行。 该 `LIMIT m OFFSET n` 也支持语法。 + +`n` 和 `m` 必须是非负整数。 + +如果没有 `ORDER BY` 明确排序结果的子句,结果可能是任意的和不确定的。 + +### UNION ALL条款 {#union-all-clause} + +您可以使用UNION ALL来组合任意数量的查询。 示例: ``` sql SELECT CounterID, 1 AS table, toInt64(count()) AS c @@ -689,65 +1124,64 @@ SELECT CounterID, 2 AS table, sum(Sign) AS c HAVING c > 0 ``` -仅支持UNION ALL,不支持其他UNION规则(UNION DISTINCT)。如果你需要UNION DISTINCT,你可以使用UNION ALL中包含SELECT DISTINCT的子查询的方式。 +只支持UNION ALL。 不支持常规联合(UNION DISTINCT)。 如果您需要UNION DISTINCT,则可以从包含UNION ALL的子查询中编写SELECT DISTINCT。 -UNION ALL中的查询可以同时运行,它们的结果将被混合到一起。 +作为UNION ALL部分的查询可以同时运行,并且它们的结果可以混合在一起。 -这些查询的结果结果必须相同(列的数量和类型)。列名可以是不同的。在这种情况下,最终结果的列名将从第一个查询中获取。UNION会为查询之间进行类型转换。例如,如果组合的两个查询中包含相同的字段,并且是类型兼容的`Nullable`和non-`Nullable`,则结果将会将该字段转换为`Nullable`类型的字段。 +结果的结构(列的数量和类型)必须与查询匹配。 但列名可能不同。 在这种情况下,最终结果的列名将从第一个查询中获取。 对联合执行类型转换。 例如,如果合并的两个查询具有相同的字段与非-`Nullable` 和 `Nullable` 从兼容类型的类型,由此产生的 `UNION ALL` 有一个 `Nullable` 类型字段。 -作为UNION ALL查询的部分不能包含在括号内。ORDER BY与LIMIT子句应该被应用在每个查询中,而不是最终的查询中。如果你需要做最终结果转换,你可以将UNION ALL作为一个子查询包含在FROM子句中。 +作为UNION ALL部分的查询不能括在括号中。 ORDER BY和LIMIT应用于单独的查询,而不是最终结果。 如果您需要将转换应用于最终结果,则可以将所有带有UNION ALL的查询放在FROM子句的子查询中。 -### INTO OUTFILE 子句 {#into-outfile-zi-ju} +### INTO OUTFILE条款 {#into-outfile-clause} -`INTO OUTFILE filename` 子句用于将查询结果重定向输出到指定文件中(filename是一个字符串类型的值)。 -与MySQL不同,执行的结果文件将在客户端建立,如果文件已存在,查询将会失败。 -此命令可以工作在命令行客户端与clickhouse-local中(通过HTTP借口发送将会失败)。 +添加 `INTO OUTFILE filename` 子句(其中filename是字符串文字),用于将查询输出重定向到指定的文件。 +与MySQL相比,该文件是在客户端创建的。 如果具有相同文件名的文件已经存在,则查询将失败。 +此功能在命令行客户端和clickhouse-local中可用(通过HTTP接口发送的查询将失败)。 -默认的输出格式是TabSeparated(与命令行客户端的批处理模式相同)。 +默认输出格式为TabSeparated(与命令行客户端批处理模式相同)。 -### FORMAT 子句 {#format-zi-ju} +### 格式子句 {#format-clause} -‘FORMAT format’ 子句用于指定返回数据的格式。 -你可以使用它方便的转换或创建数据的转储。 -更多信息,参见«输入输出格式»部分。 -如果不存在FORMAT子句,则使用默认的格式,这将取决与DB的配置以及所使用的客户端。对于批量模式的HTTP客户端和命令行客户端而言,默认的格式是TabSeparated。对于交互模式下的命令行客户端,默认的格式是PrettyCompact(它有更加美观的格式)。 +指定 ‘FORMAT format’ 获取任何指定格式的数据。 +为了方便起见,您可以使用它或创建转储。 +有关详细信息,请参阅部分 “Formats”. +如果省略FORMAT子句,则使用默认格式,这取决于用于访问数据库的设置和接口。 对于http接口和批处理模式下的命令行客户端,默认格式为TabSeparated。 对于交互模式下的命令行客户端,默认格式为PrettyCompact(它具有吸引力和紧凑的表)。 -当使用命令行客户端时,数据以内部高效的格式在服务器和客户端之间进行传递。客户端将单独的解析FORMAT子句,以帮助数据格式的转换(这将减轻网络和服务器的负载)。 +使用命令行客户端时,数据以内部高效格式传递给客户端。 客户端独立解释查询的FORMAT子句并格式化数据本身(从而减轻网络和服务器的负载)。 -### IN 运算符 {#select-in-operators} +### 在运营商 {#select-in-operators} -对于`IN`、`NOT IN`、`GLOBAL IN`、`GLOBAL NOT IN`操作符被分别实现,因为它们的功能非常丰富。 +该 `IN`, `NOT IN`, `GLOBAL IN`,和 `GLOBAL NOT IN` 运算符是单独复盖的,因为它们的功能相当丰富。 -运算符的左侧是单列或列的元组。 +运算符的左侧是单列或元组。 -示例: +例: ``` sql SELECT UserID IN (123, 456) FROM ... SELECT (CounterID, UserID) IN ((34, 123), (101500, 456)) FROM ... ``` -如果左侧是单个列并且是一个索引,并且右侧是一组常量时,系统将使用索引来处理查询。 +如果左侧是索引中的单列,而右侧是一组常量,则系统将使用索引处理查询。 -不要在列表中列出太多的值(百万)。如果数据集很大,将它们放入临时表中(可以参考«»), 然后使用子查询。 -Don’t list too many values explicitly (i.e. millions). If a data set is large, put it in a temporary table (for example, see the section «External data for query processing»), then use a subquery. +Don't list too many values explicitly (i.e. millions). If a data set is large, put it in a temporary table (for example, see the section “External data for query processing”),然后使用子查询。 -右侧可以是一个由常量表达式组成的元组列表(像上面的例子一样),或者是一个数据库中的表的名称,或是一个包含在括号中的子查询。 +运算符的右侧可以是一组常量表达式、一组带有常量表达式的元组(如上面的示例所示),或括号中的数据库表或SELECT子查询的名称。 -如果右侧是一个表的名字(例如,`UserID IN users`),这相当于`UserID IN (SELECT * FROM users)`。在查询与外部数据表组合使用时可以使用该方法。例如,查询与包含user IDS的’users’临时表一起被发送的同时需要对结果进行过滤时。 +如果运算符的右侧是表的名称(例如, `UserID IN users`),这相当于子查询 `UserID IN (SELECT * FROM users)`. 使用与查询一起发送的外部数据时,请使用此选项。 例如,查询可以与一组用户Id一起发送到 ‘users’ 应过滤的临时表。 -如果操作符的右侧是一个Set引擎的表时(数据总是在内存中准备好),则不会每次都为查询创建新的数据集。 +如果运算符的右侧是具有Set引擎的表名(始终位于RAM中的准备好的数据集),则不会为每个查询重新创建数据集。 -子查询可以指定一个列以上的元组来进行过滤。 +子查询可以指定多个用于筛选元组的列。 示例: ``` sql SELECT (CounterID, UserID) IN (SELECT CounterID, UserID FROM ...) FROM ... ``` -IN操作符的左右两侧应具有相同的类型。 +IN运算符左侧和右侧的列应具有相同的类型。 -IN操作符的子查询中可以出现任意子句,包含聚合函数与lambda函数。 +IN运算符和子查询可能出现在查询的任何部分,包括聚合函数和lambda函数。 示例: ``` sql @@ -764,64 +1198,74 @@ GROUP BY EventDate ORDER BY EventDate ASC ``` - ┌──EventDate─┬────ratio─┐ - │ 2014-03-17 │ 1 │ - │ 2014-03-18 │ 0.807696 │ - │ 2014-03-19 │ 0.755406 │ - │ 2014-03-20 │ 0.723218 │ - │ 2014-03-21 │ 0.697021 │ - │ 2014-03-22 │ 0.647851 │ - │ 2014-03-23 │ 0.648416 │ - └────────────┴──────────┘ +``` text +┌──EventDate─┬────ratio─┐ +│ 2014-03-17 │ 1 │ +│ 2014-03-18 │ 0.807696 │ +│ 2014-03-19 │ 0.755406 │ +│ 2014-03-20 │ 0.723218 │ +│ 2014-03-21 │ 0.697021 │ +│ 2014-03-22 │ 0.647851 │ +│ 2014-03-23 │ 0.648416 │ +└────────────┴──────────┘ +``` -为3月17日之后的每一天计算与3月17日访问该网站的用户浏览网页的百分比。 -IN子句中的子查询仅在单个服务器上运行一次。不能够是相关子查询。 +对于3月17日后的每一天,计算3月17日访问该网站的用户所做的浏览量百分比。 +IN子句中的子查询始终只在单个服务器上运行一次。 没有依赖子查询。 -#### NULL 处理 {#null-chu-li-1} +#### 空处理 {#null-processing-1} 在处理中,IN操作符总是假定 [NULL](../syntax.md#null-literal) 值的操作结果总是等于`0`,而不管`NULL`位于左侧还是右侧。`NULL`值不应该包含在任何数据集中,它们彼此不能够对应,并且不能够比较。 -下面的示例中有一个`t_null`表: +下面是一个例子 `t_null` 表: - ┌─x─┬────y─┐ - │ 1 │ ᴺᵁᴸᴸ │ - │ 2 │ 3 │ - └───┴──────┘ +``` text +┌─x─┬────y─┐ +│ 1 │ ᴺᵁᴸᴸ │ +│ 2 │ 3 │ +└───┴──────┘ +``` -运行查询`SELECT x FROM t_null WHERE y IN (NULL,3)`将得到如下结果: +运行查询 `SELECT x FROM t_null WHERE y IN (NULL,3)` 为您提供以下结果: - ┌─x─┐ - │ 2 │ - └───┘ +``` text +┌─x─┐ +│ 2 │ +└───┘ +``` -你可以看到在查询结果中不存在`y = NULL`的结果。这是因为ClickHouse无法确定`NULL`是否包含在`(NULL,3)`数据集中,对于这次比较操作返回了`0`,并且在`SELECT`的最终输出中排除了这行。 +你可以看到,在其中的行 `y = NULL` 被抛出的查询结果。 这是因为ClickHouse无法决定是否 `NULL` 包含在 `(NULL,3)` 设置,返回 `0` 作为操作的结果,和 `SELECT` 从最终输出中排除此行。 - SELECT y IN (NULL, 3) - FROM t_null +``` sql +SELECT y IN (NULL, 3) +FROM t_null +``` - ┌─in(y, tuple(NULL, 3))─┐ - │ 0 │ - │ 1 │ - └───────────────────────┘ +``` text +┌─in(y, tuple(NULL, 3))─┐ +│ 0 │ +│ 1 │ +└───────────────────────┘ +``` #### 分布式子查询 {#select-distributed-subqueries} -对于带有子查询的(类似与JOINs)IN中,有两种选择:普通的`IN`/`JOIN`与`GLOBAL IN` / `GLOBAL JOIN`。它们对于分布式查询的处理运行方式是不同的。 +带子查询的IN-s有两个选项(类似于连接):normal `IN` / `JOIN` 和 `GLOBAL IN` / `GLOBAL JOIN`. 它们在分布式查询处理的运行方式上有所不同。 -!!! 注意 "注意" - 请记住,下面描述的算法可能因为根据 [设置](../../operations/settings/settings.md) 配置的不同而不同。 +!!! attention "注意" + 请记住,下面描述的算法可能会有不同的工作方式取决于 [设置](../../operations/settings/settings.md) `distributed_product_mode` 设置。 -当使用普通的IN时,查询总是被发送到远程的服务器,并且在每个服务器中运行«IN»或«JOIN»子句中的子查询。 +当使用常规IN时,查询被发送到远程服务器,并且它们中的每个服务器都在运行子查询 `IN` 或 `JOIN` 条款 -当使用`GLOBAL IN` / `GLOBAL JOIN`时,首先会为`GLOBAL IN` / `GLOBAL JOIN`运行所有子查询,并将结果收集到临时表中,并将临时表发送到每个远程服务器,并使用该临时表运行查询。 +使用时 `GLOBAL IN` / `GLOBAL JOINs`,首先所有的子查询都运行 `GLOBAL IN` / `GLOBAL JOINs`,并将结果收集在临时表中。 然后将临时表发送到每个远程服务器,其中使用此临时数据运行查询。 -对于非分布式查询,请使用普通的`IN` / `JOIN`。 +对于非分布式查询,请使用常规 `IN` / `JOIN`. -在分布式查询中使用`IN` / `JOIN`子句中使用子查询需要小心。 +在使用子查询时要小心 `IN` / `JOIN` 用于分布式查询处理的子句。 -让我们来看一些例子。假设集群中的每个服务器都存在一个正常表**local\_table**。与一个分布式表**distributed\_table**。 +让我们来看看一些例子。 假设集群中的每个服务器都有一个正常的 **local\_table**. 每个服务器还具有 **distributed\_table** 表与 **分布** 类型,它查看群集中的所有服务器。 -对于所有查询**distributed\_table**的查询,查询会被发送到所有的远程服务器并使用**local\_table**表运行查询。 +对于查询 **distributed\_table**,查询将被发送到所有远程服务器,并使用以下命令在其上运行 **local\_table**. 例如,查询 @@ -829,108 +1273,107 @@ IN子句中的子查询仅在单个服务器上运行一次。不能够是相关 SELECT uniq(UserID) FROM distributed_table ``` -将发送如下查询到所有远程服务器 +将被发送到所有远程服务器 ``` sql SELECT uniq(UserID) FROM local_table ``` -这时将并行的执行它们,直到达到可以组合数据的中间结果状态。然后中间结果将返回到请求服务器并在请求服务器上进行合并,最终将结果发送给客户端。 +并且并行运行它们中的每一个,直到达到可以结合中间结果的阶段。 然后将中间结果返回给请求者服务器并在其上合并,并将最终结果发送给客户端。 -现在让我运行一个带有IN的查询: +现在让我们检查一个查询IN: ``` sql SELECT uniq(UserID) FROM distributed_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM local_table WHERE CounterID = 34) ``` -- 计算两个站点的用户交集。 +- 计算两个网站的受众的交集。 -此查询将被发送给所有的远程服务器 +此查询将以下列方式发送到所有远程服务器 ``` sql SELECT uniq(UserID) FROM local_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM local_table WHERE CounterID = 34) ``` -换句话说,IN子句中的数据集将被在每台服务器上被独立的收集,仅与每台服务器上的本地存储上的数据计算交集。 +换句话说,IN子句中的数据集将在每台服务器上独立收集,仅在每台服务器上本地存储的数据中收集。 -如果您已经将数据分散到了集群的每台服务器上,并且单个UserID的数据完全分布在单个服务器上,那么这将是正确且最佳的查询方式。在这种情况下,所有需要的数据都可以在每台服务器的本地进行获取。否则,结果将是不准确的。我们将这种查询称为«local IN»。 +如果您已经为此情况做好准备,并且已经将数据分散到群集服务器上,以便单个用户Id的数据完全驻留在单个服务器上,则这将正常和最佳地工作。 在这种情况下,所有必要的数据将在每台服务器上本地提供。 否则,结果将是不准确的。 我们将查询的这种变体称为 “local IN”. -为了修正这种在数据随机分布的集群中的工作,你可以在子查询中使用**distributed\_table**。查询将更改为这样: +若要更正数据在群集服务器上随机传播时查询的工作方式,可以指定 **distributed\_table** 在子查询中。 查询如下所示: ``` sql SELECT uniq(UserID) FROM distributed_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM distributed_table WHERE CounterID = 34) ``` -此查询将被发送给所有的远程服务器 +此查询将以下列方式发送到所有远程服务器 ``` sql SELECT uniq(UserID) FROM local_table WHERE CounterID = 101500 AND UserID IN (SELECT UserID FROM distributed_table WHERE CounterID = 34) ``` -子查询将在每个远程服务器上执行。因为子查询使用分布式表,所有每个远程服务器上的子查询将查询再次发送给所有的远程服务器 +子查询将开始在每个远程服务器上运行。 由于子查询使用分布式表,因此每个远程服务器上的子查询将重新发送到每个远程服务器 ``` sql SELECT UserID FROM local_table WHERE CounterID = 34 ``` -例如,如果你拥有100台服务器的集群,执行整个查询将需要10,000次请求,这通常被认为是不可接受的。 +例如,如果您有100台服务器的集群,则执行整个查询将需要10,000个基本请求,这通常被认为是不可接受的。 -在这种情况下,你应该使用GLOBAL IN来替代IN。让我们看一下它是如何工作的。 +在这种情况下,应始终使用GLOBAL IN而不是IN。 让我们来看看它是如何工作的查询 ``` sql SELECT uniq(UserID) FROM distributed_table WHERE CounterID = 101500 AND UserID GLOBAL IN (SELECT UserID FROM distributed_table WHERE CounterID = 34) ``` -在请求服务器上运行子查询 +请求者服务器将运行子查询 ``` sql SELECT UserID FROM distributed_table WHERE CounterID = 34 ``` -将结果放入内存中的临时表中。然后将请求发送到每一台远程服务器 +结果将被放在RAM中的临时表中。 然后请求将被发送到每个远程服务器 ``` sql SELECT uniq(UserID) FROM local_table WHERE CounterID = 101500 AND UserID GLOBAL IN _data1 ``` -临时表`_data1`也会随着查询一起发送到每一台远程服务器(临时表的名称由具体实现定义)。 +和临时表 `_data1` 将通过查询发送到每个远程服务器(临时表的名称是实现定义的)。 -这比使用普通的IN更加理想,但是,请注意以下几点: +这比使用正常IN更优化。 但是,请记住以下几点: -1. 创建临时表时,数据不是唯一的,为了减少通过网络传输的数据量,请在子查询中使用DISTINCT(你不需要在普通的IN中这么做) -2. 临时表将发送到所有远程服务器。其中传输不考虑网络的拓扑结构。例如,如果你有10个远程服务器存在与请求服务器非常远的数据中心中,则数据将通过通道发送数据到远程数据中心10次。使用GLOBAL IN时应避免大数据集。 -3. 当向远程服务器发送数据时,网络带宽的限制是不可配置的,这可能会网络的负载造成压力。 -4. 尝试将数据跨服务器分布,这样你将不需要使用GLOBAL IN。 -5. 如果你需要经常使用GLOBAL IN,请规划你的ClickHouse集群位置,以便副本之间不存在跨数据中心,并且它们之间具有快速的网络交换能力,以便查询可以完全在一个数据中心内完成。 +1. 创建临时表时,数据不是唯一的。 要减少通过网络传输的数据量,请在子查询中指定DISTINCT。 (你不需要为正常人做这个。) +2. 临时表将被发送到所有远程服务器。 传输不考虑网络拓扑。 例如,如果10个远程服务器驻留在与请求者服务器非常远程的数据中心中,则数据将通过通道发送10次到远程数据中心。 使用GLOBAL IN时尽量避免使用大型数据集。 +3. 将数据传输到远程服务器时,无法配置网络带宽限制。 您可能会使网络过载。 +4. 尝试跨服务器分发数据,以便您不需要定期使用GLOBAL IN。 +5. 如果您需要经常使用GLOBAL IN,请规划ClickHouse集群的位置,以便单个副本组驻留在不超过一个数据中心中,并且它们之间具有快速网络,以便可以完全在单个数据中心内处理查询。 -另外,在`GLOBAL IN`子句中使用本地表也是有用的,比如,本地表仅在请求服务器上可用,并且您希望在远程服务器上使用来自本地表的数据。 +这也是有意义的,在指定一个本地表 `GLOBAL IN` 子句,以防此本地表仅在请求者服务器上可用,并且您希望在远程服务器上使用来自它的数据。 ### 极端值 {#extreme-values} -除了结果外,你还可以获得结果列的最大值与最小值,可以将**极端**配置设置成1来做到这一点。最大值最小值的计算是针对于数字类型,日期类型进行计算的,对于其他列,将会输出默认值。 +除了结果之外,还可以获取结果列的最小值和最大值。 要做到这一点,设置 **极端** 设置为1。 最小值和最大值是针对数字类型、日期和带有时间的日期计算的。 对于其他列,默认值为输出。 -额外计算的两行结果 - 最大值与最小值,这两行额外的结果仅在JSON\*, TabSeparated\*, and Pretty\* 格式与其他行分开的输出方式输出,不支持其他输出格式。 +An extra two rows are calculated – the minimums and maximums, respectively. These extra two rows are output in `JSON*`, `TabSeparated*`,和 `Pretty*` [格式](../../interfaces/formats.md),与其他行分开。 它们不是其他格式的输出。 -在JSON\*格式中,Extreme值在单独的’extremes’字段中。在TabSeparated\*格式中,在其他结果与’totals’之后输出,并使用空行与其分隔。在Pretty\* 格式中,将在其他结果与’totals’后以单独的表格输出。 +在 `JSON*` 格式时,极端值在一个单独的输出 ‘extremes’ 场。 在 `TabSeparated*` 格式中,该行来的主要结果之后,和之后 ‘totals’ 如果存在。 它前面有一个空行(在其他数据之后)。 在 `Pretty*` 格式中,该行被输出为一个单独的表之后的主结果,和之后 `totals` 如果存在。 -如果在计算Extreme值的同时包含LIMIT。extremes的计算结果将包含offset跳过的行。在流式的请求中,它可能还包含多余LIMIT的少量行的值。 +极值计算之前的行 `LIMIT`,但之后 `LIMIT BY`. 但是,使用时 `LIMIT offset, size`,之前的行 `offset` 都包含在 `extremes`. 在流请求中,结果还可能包括少量通过的行 `LIMIT`. -### 注意事项 {#zhu-yi-shi-xiang} +### 注 {#notes} -不同于MySQL, `GROUP BY`与`ORDER BY`子句不支持使用列的位置信息作为参数,但这实际上是符合SQL标准的。 -例如,`GROUP BY 1, 2`将被解释为按照常量进行分组(即,所有的行将会被聚合成一行)。 +该 `GROUP BY` 和 `ORDER BY` 子句不支持位置参数。 这与MySQL相矛盾,但符合标准SQL。 +例如, `GROUP BY 1, 2` will be interpreted as grouping by constants (i.e. aggregation of all rows into one). -可以在查询的任何部分使用AS。 +您可以使用同义词 (`AS` 别名)在查询的任何部分。 -可以在查询的任何部分添加星号,而不仅仅是表达式。在分析查询时,星号被替换为所有的列(不包含`MATERIALIZED`与`ALIAS`的列)。 -只有少数情况下使用星号是合理的: +您可以在查询的任何部分而不是表达式中添加星号。 分析查询时,星号将展开为所有表列的列表(不包括 `MATERIALIZED` 和 `ALIAS` 列)。 只有少数情况下使用星号是合理的: - 创建表转储时。 -- 对于仅包含几个列的表,如系统表. -- 获取表中的列信息。在这种情况下应该使用`LIMIT 1`。但是,更好的办法是使用`DESC TABLE`。 -- 当使用`PREWHERE`在少数的几个列上做强过滤时。 -- 在子查询中(因为外部查询不需要的列被排除在子查询之外)。 +- 对于只包含几列的表,例如系统表。 +- 获取有关表中哪些列的信息。 在这种情况下,设置 `LIMIT 1`. 但最好使用 `DESC TABLE` 查询。 +- 当对少量柱进行强过滤时,使用 `PREWHERE`. +- 在子查询中(因为外部查询不需要的列从子查询中排除)。 -在所有的其他情况下,我们不建议使用星号,因为它是列式数据库的缺点而不是优点。 +在所有其他情况下,我们不建议使用星号,因为它只给你一个列DBMS的缺点,而不是优点。 换句话说,不建议使用星号。 -[来源文章](https://clickhouse.tech/docs/zh/query_language/select/) +[原始文章](https://clickhouse.tech/docs/en/query_language/select/)