Quelle est la différence entre les opérateurs cube, rollup et groupBy?

la Question est dans le titre. Je ne trouve pas de documentation détaillée concernant les différences.

je remarque une différence parce que lors de l'échange d'appels de fonctions cube et groupBy, j'obtiens des résultats différents. J'ai remarqué que pour le résultat en utilisant 'cube', j'ai eu beaucoup de valeurs nulles sur les expressions que j'ai souvent groupées.

25
demandé sur user8371915 2016-06-22 21:01:10
la source

1 ответов

ils sont destinés à travailler de la même manière. groupBy est simplement l'équivalent de GROUP BY l'article dans le standard SQL. En d'autres termes

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

est l'équivalent de:

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

cube est équivalent à CUBE extension à GROUP BY. Il prend une liste de colonnes et applique des expressions agrégées à toutes les combinaisons possibles des colonnes de regroupement. Disons que vous avez données comme ceci:

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|
// +---+---+

et vous calculer cube(x, y) avec le comte comme une agrégation:

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
// +----+----+-----+

Une fonction similaire au cuberollup qui calcule les sous-totaux hiérarchiques de gauche à droite:

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
// +----+----+-----+

juste à titre de comparaison permet de voir le résultat de 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
// +---+---+-----+

Pour résumer:

  • Lors de l'utilisation de brut GROUP BY chaque ligne n'est incluse qu'une seule fois dans le résumé correspondant.
  • GROUP BY CUBE(..) chaque ligne est inclus dans résumé de chaque combinaison de niveaux qu'il représente, jokers inclus. Logiquement, ce qui est montré ci-dessus est équivalent à quelque chose comme ceci (en supposant que nous pourrions utiliser NULL espaces réservés):

    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
    
  • GROUP BY ROLLUP(...) est similaire à CUBE mais fonctionne hiérarchiquement en remplissant des colonnes de gauche à droite.

    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 et CUBE proviennent d'extensions d'entreposage de données, donc si vous voulez obtenir une meilleure compréhension comment travaux vous pouvez également vérifier la documentation de vos rdmbs préférés. Par exemple PostgreSQL introduit à la fois en 9.5 et ceux-ci sont relativement bien documentés.

49
répondu zero323 2016-06-22 22:23:01
la source