2016-06-22 20 views
18

La domanda è praticamente nel titolo. Non riesco a trovare alcuna documentazione dettagliata riguardante le differenze.Qual è la differenza tra gli operatori cubo, cumulativo e groupBy?

Noto una differenza perché quando si scambiano le chiamate di cubo e di gruppo con le funzioni, ottengo risultati diversi. Ho notato che per il risultato che usa "cubo", ho ottenuto molti valori nulli sulle espressioni che ho spesso raggruppato.

risposta

38

Questi non sono progettati per funzionare nello stesso modo. groupBy è semplicemente un equivalente della clausola GROUP BY in SQL standard. In altre parole

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

è equivalente a:

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

cube equivale a CUBE estensione GROUP BY. Prende un elenco di colonne e applica espressioni aggregate a tutte le possibili combinazioni delle colonne di raggruppamento. Diciamo che si dispone di dati di questo tipo:

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

e sei al computer cube(x, y) con conteggio come aggregazione:

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 funzione simile a cube è rollup che calcola i totali parziali gerarchiche da sinistra a destra :

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

Ju st per il confronto permette di vedere il risultato di pianura 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 
// +---+---+-----+ 

In sintesi:

  • Quando si utilizza pianura GROUP BY ogni riga è incluso solo una volta nel suo corrispondente sintesi.
  • Con GROUP BY CUBE(..) ogni riga è inclusa nel riepilogo di ciascuna combinazione di livelli che rappresenta, caratteri jolly inclusi. Logicamente, il mostrata sopra è equivalente a qualcosa di simile (supponendo potremmo utilizzare NULL segnaposti):

    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(...) è simile a CUBE ma funziona gerarchicamente compilando colonne da sinistra a destra.

    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 e CUBE provengono da estensioni di data warehousing, quindi se si desidera ottenere una migliore comprensione di come funziona è anche possibile controllare la documentazione dei tuoi RDMBS preferiti. Ad esempio, PostgreSQL ha introdotto sia in 9.5 che in these are relatively well documented.

Problemi correlati