Saltar al contenido

¿Cuál es la diferencia entre los operadores cube, rollup y groupBy?

Traemos la mejor solución que hallamos on line. Nosotros esperamos que te sea de ayuda y si quieres compartir algún detalle que nos pueda ayudar a perfeccionar nuestra información hazlo con libertad.

Solución:

Estos no están destinados a funcionar de la misma manera. groupBy es simplemente un equivalente de la GROUP BY cláusula en SQL estándar. En otras palabras

table.groupBy($"foo", $"bar")

es equivalente a:

SELECT foo, bar, [agg-expressions] FROM table GROUP BY foo, bar

cube es equivalente a CUBE extensión a GROUP BY. Toma una lista de columnas y aplica expresiones agregadas a todas las combinaciones posibles de las columnas de agrupación. Digamos que tienes datos como este:

val df = Seq(("foo", 1L), ("foo", 2L), ("bar", 2L), ("bar", 2L)).toDF("x", "y")
df.show

// +---+---+
// |  x|  y|
// +---+---+
// |foo|  1|
// |foo|  2|
// |bar|  2|
// |bar|  2|
// +---+---+

y tu calculas cube(x, y) con contar como una agregación:

df.cube($"x", $"y").count.show

// +----+----+-----+     
// |   x|   y|count|
// +----+----+-----+
// |null|   1|    1|   <- count of records where y = 1
// |null|   2|    3|   <- count of records where y = 2
// | foo|null|    2|   <- count of records where x = foo
// | bar|   2|    2|   <- count of records where x = bar AND y = 2
// | foo|   1|    1|   <- count of records where x = foo AND y = 1
// | foo|   2|    1|   <- count of records where x = foo AND y = 2
// |null|null|    4|   <- total count of records
// | bar|null|    2|   <- count of records where x = bar
// +----+----+-----+

Una función similar a cube es rollup que calcula los subtotales jerárquicos de izquierda a derecha:

df.rollup($"x", $"y").count.show
// +----+----+-----+
// |   x|   y|count|
// +----+----+-----+
// | foo|null|    2|   <- count where x is fixed to foo
// | bar|   2|    2|   <- count where x is fixed to bar and y is fixed to  2
// | foo|   1|    1|   ...
// | foo|   2|    1|   ...
// |null|null|    4|   <- count where no column is fixed
// | bar|null|    2|   <- count where x is fixed to bar
// +----+----+-----+

Solo para comparar, veamos el resultado de la simple groupBy:

df.groupBy($"x", $"y").count.show

// +---+---+-----+
// |  x|  y|count|
// +---+---+-----+
// |foo|  1|    1|   <- this is identical to x = foo AND y = 1 in CUBE or ROLLUP
// |foo|  2|    1|   <- this is identical to x = foo AND y = 2 in CUBE or ROLLUP
// |bar|  2|    2|   <- this is identical to x = bar AND y = 2 in CUBE or ROLLUP
// +---+---+-----+

Para resumir:

  • Cuando se usa simple GROUP BY cada fila se incluye una sola vez en su resumen correspondiente.
  • Con GROUP BY CUBE(..) cada fila se incluye en el resumen de cada combinación de niveles que representa, comodines incluidos. Lógicamente, lo que se muestra arriba es equivalente a algo como esto (suponiendo que podamos usar NULL marcadores de posición):

    SELECT NULL, NULL, COUNT(*) FROM table
    UNION ALL
    SELECT x,    NULL, COUNT(*) FROM table GROUP BY x
    UNION ALL
    SELECT NULL, y,    COUNT(*) FROM table GROUP BY y
    UNION ALL
    SELECT x,    y,    COUNT(*) FROM table GROUP BY x, y
    
  • Con GROUP BY ROLLUP(...) es parecido a CUBE pero funciona jerárquicamente llenando columnas de izquierda a derecha.

    SELECT NULL, NULL, COUNT(*) FROM table
    UNION ALL
    SELECT x,    NULL, COUNT(*) FROM table GROUP BY x
    UNION ALL
    SELECT x,    y,    COUNT(*) FROM table GROUP BY x, y
    

ROLLUP y CUBE provienen de extensiones de almacenamiento de datos, por lo que si desea comprender mejor cómo funciona esto, también puede consultar la documentación de su RDMBS favorito. Por ejemplo, PostgreSQL introdujo ambos en 9.5 y están relativamente bien documentados.

Reseñas y calificaciones

Si tienes alguna cuestión o capacidad de enriquecer nuestro noticia puedes añadir una nota y con mucho gusto lo leeremos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *