DOCS-624: re-generate select.md (#10689)

* lost redirect

* re-generate select.md
This commit is contained in:
Ivan Blinkov 2020-05-06 13:20:58 +03:00 committed by GitHub
parent bd9df858ed
commit e5c892eecf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 4954 additions and 664 deletions

View File

@ -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 <expr_list>
@ -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 <left_subquery>
Los nombres de tabla se pueden especificar en lugar de `<left_subquery>` y `<right_subquery>`. 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 `<right_subquery>` 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/) <!--hide-->

View File

@ -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 <expr_list>
@ -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) الگوریتم. تاتر طول می کشد `<right_subquery>` و یک جدول هش را در رم ایجاد می کند. اگر شما نیاز به محدود کردن پیوستن به مصرف حافظه عملیات استفاده از تنظیمات زیر:
- [\_پاک کردن \_روشن گرافیک](../../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/) <!--hide-->

File diff suppressed because it is too large Load Diff

View File

@ -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` サブクエリでは、クエリはO1量の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 <expr_list>
@ -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 <left_subquery>
#### 複数の結合 {#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) アルゴリズムだ クリックハウスは、 `<right_subquery>` 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\_bytotals. つまり, 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\_bytotals. それ以外の場合は、含めないでください。
`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/) <!--hide-->

View File

@ -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

View File

@ -0,0 +1 @@
../util.py

View File

@ -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 Dbmslerde 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` 0dan 1e kadar olan sayıdır.</br>Sorgu üzerinde yürütülür `k` verilerin kesir. Mesela, `SAMPLE 0.1` sorguyu verilerin %10unda çalıştırır. [Daha fazla bilgi edinin](#select-sample-k) |
| `SAMPLE k` | Burada `k` 0'dan 1'e kadar olan sayıdır.</br>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.</br>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` 0dan 1e kadar olan sayılardır.</br>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.</br>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` 0dan 1e 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` 0dan 1e 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` 0dan 1e kadar olan sayılardır. Örnekler aşağıda g
SAMPLE 1/10
```
Bu örnekte, örnek tüm verilerin 1/10udur:
Bu örnekte, örnek tüm verilerin 1/10'udur:
`[++------------]`
@ -244,13 +244,13 @@ Bu örnekte, örnek tüm verilerin 1/10udur:
SAMPLE 1/10 OFFSET 1/2
```
Burada, verilerin ikinci yarısından %10luk 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 <expr_list>
@ -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 <left_subquery>
Tablo adları yerine belirtilebilir `<left_subquery>` ve `<right_subquery>`. 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ıı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 `<right_subquery>` 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ıı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ıı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.
ı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/) <!--hide-->

File diff suppressed because it is too large Load Diff