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.