2016-06-22 19 views

Odpowiedz

38

Nie są przeznaczone do pracy w ten sam sposób. groupBy jest po prostu odpowiednikiem klauzuli GROUP BY w standardowym SQL. Innymi słowy

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

odpowiada:

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

cube jest równoważna CUBE przedłużenie GROUP BY. Wykonuje listę kolumn i stosuje wyrażenia zbiorcze do wszystkich możliwych kombinacji kolumn grupowania. Powiedzmy, że masz dane tak:

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

i obliczyć cube(x, y) z count jako agregacji:

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

Podobna funkcja do cube jest rollup który oblicza hierarchicznych sum od lewej do prawej :

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 dla porównania pozwala zobaczyć wynik zwykłego 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 
// +---+---+-----+ 

Podsumowując:

  • Przy użyciu zwykłego GROUP BY każdy wiersz jest dołączony tylko raz w odpowiadającym jej podsumowanie.
  • Każdy z wierszy zawiera GROUP BY CUBE(..) podsumowanie każdej kombinacji poziomów, które reprezentuje, w tym symbole wieloznaczne. Logicznie rzecz biorąc, pokazany powyżej jest równoznaczne z czymś takim (zakładając, że mogliśmy korzystać NULL zastępcze):

    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 
    
  • Z GROUP BY ROLLUP(...) jest podobna do CUBE ale działa hierarchicznie poprzez wypełnienie colums od lewej do prawej.

    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 i CUBE pochodzą z rozszerzeniami hurtowni danych, więc jeśli chcesz, aby lepiej zrozumieć, jak to działa można również sprawdzić dokumentację swoich ulubionych RDMBS. Na przykład PostgreSQL wprowadził zarówno w 9.5, jak i these are relatively well documented.