ClickHouse/docs/es/sql-reference/statements/select/group-by.md
2020-10-13 20:23:29 +03:00

9.3 KiB
Raw Blame History

machine_translated machine_translated_rev
true 72537a2d52

GRUPO POR Cláusula

GROUP BY cláusula cambia el SELECT consulta en un modo de agregación, que funciona de la siguiente manera:

  • GROUP BY clause contiene una lista de expresiones (o una sola expresión, que se considera la lista de longitud uno). Esta lista actúa como un “grouping key”, mientras que cada expresión individual será referida como un “key expressions”.
  • Todas las expresiones en el SELECT, HAVING, y ORDER BY clausula deber se calculará basándose en expresiones clave o en funciones agregadas sobre expresiones no clave (incluidas columnas simples). En otras palabras, cada columna seleccionada de la tabla debe usarse en una expresión clave o dentro de una función agregada, pero no en ambas.
  • Resultado de la agregación SELECT la consulta contendrá tantas filas como valores únicos de “grouping key” en la tabla de origen. Por lo general, esto reduce significativamente el recuento de filas, a menudo en órdenes de magnitud, pero no necesariamente: el recuento de filas se mantiene igual si todo “grouping key” los valores fueron distintos.

!!! note "Nota" Hay una forma adicional de ejecutar la agregación sobre una tabla. Si una consulta contiene columnas de tabla solo dentro de funciones agregadas, el GROUP BY clause se puede omitir, y se asume la agregación por un conjunto vacío de claves. Tales consultas siempre devuelven exactamente una fila.

Procesamiento NULL

Para agrupar, ClickHouse interpreta NULL como valor, y NULL==NULL. Se diferencia de NULL procesamiento en la mayoría de los otros contextos.

Aquí hay un ejemplo para mostrar lo que esto significa.

Supongamos que tienes esta tabla:

┌─x─┬────y─┐
│ 1 │    2 │
│ 2 │ ᴺᵁᴸᴸ │
│ 3 │    2 │
│ 3 │    3 │
│ 3 │ ᴺᵁᴸᴸ │
└───┴──────┘

Consulta SELECT sum(x), y FROM t_null_big GROUP BY y resultados en:

┌─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

Si el WITH TOTALS se especifica el modificador, 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 solo se produce en JSON*, TabSeparated*, y Pretty* formatos, por separado de las otras filas:

  • En JSON* formatos, esta fila se muestra como una totals campo.
  • En TabSeparated* formatea, la fila viene después del resultado principal, precedida 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.
  • En los otros formatos no está disponible.

WITH TOTALS se puede ejecutar de diferentes maneras cuando HAVING está presente. El comportamiento depende de la totals_mode configuración.

Configuración del procesamiento de totales

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).

Ejemplos

Ejemplo:

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:

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().

Detalles de implementación

La agregación es una de las características más importantes de un DBMS orientado a columnas, y por lo tanto su implementación es una de las partes más optimizadas de ClickHouse. De forma predeterminada, la agregación se realiza en la memoria utilizando una tabla hash. Tiene más de 40 especializaciones que se eligen automáticamente dependiendo de “grouping key” tipos de datos.

GROUP BY en memoria externa

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 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 los datos 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: 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).