cube、rollup 和 groupBy 运算符之间有什么区别?
What is the difference between cube, rollup and groupBy operators?
标题中的问题差不多。我找不到任何关于差异的详细文档。
我确实注意到了差异,因为在交换 cube 和 groupBy 函数调用时,我得到了不同的结果。我注意到对于使用 'cube' 的结果,我在经常分组的表达式中得到了很多空值。
它们的工作方式不同。 groupBy
相当于标准 SQL 中的 GROUP BY
子句。换句话说
table.groupBy($"foo", $"bar")
相当于:
SELECT foo, bar, [agg-expressions] FROM table GROUP BY foo, bar
cube
相当于 CUBE
GROUP BY
的扩展。它采用列列表并将聚合表达式应用于分组列的所有可能组合。假设您有这样的数据:
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|
// +---+---+
然后你计算 cube(x, y)
并将计数作为聚合:
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
// +----+----+-----+
与 cube
类似的函数是 rollup
,它从左到右计算层次小计:
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
// +----+----+-----+
只是为了比较让我们看看普通 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
// +---+---+-----+
总结一下:
- 当使用普通
GROUP BY
时,每一行在其对应的摘要中只包含一次。
在 GROUP BY CUBE(..)
中,每一行都包含在它所代表的每个级别组合的摘要中,包括通配符。从逻辑上讲,上面显示的等同于这样的东西(假设我们可以使用 NULL
占位符):
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
With GROUP BY ROLLUP(...)
类似于 CUBE
,但通过从左到右填充列来分层工作。
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
和 CUBE
来自数据仓库扩展,所以如果您想更好地了解它的工作原理,您还可以查看您最喜欢的 RDMBS 的文档。例如 PostgreSQL 在 9.5 和 these are relatively well documented.
中都引入了
- 如果您不想使用 null,请先使用以下示例将其删除
Dfwithoutnull=df.na.drop("all",seq(col name 1,col name 2))
上面的表达式将删除原始数据帧中的 null
2.group 我猜你知道的。
3.rollup 和 cube 是 GROUPING SET 运算符。
Roll-up是一种多维的聚合处理元素,以层次化的方式
在立方体中,立方体不是按层次处理元素,而是在所有维度上做同样的事情。
你可以尝试grouping_id来理解抽象层次
标题中的问题差不多。我找不到任何关于差异的详细文档。
我确实注意到了差异,因为在交换 cube 和 groupBy 函数调用时,我得到了不同的结果。我注意到对于使用 'cube' 的结果,我在经常分组的表达式中得到了很多空值。
它们的工作方式不同。 groupBy
相当于标准 SQL 中的 GROUP BY
子句。换句话说
table.groupBy($"foo", $"bar")
相当于:
SELECT foo, bar, [agg-expressions] FROM table GROUP BY foo, bar
cube
相当于 CUBE
GROUP BY
的扩展。它采用列列表并将聚合表达式应用于分组列的所有可能组合。假设您有这样的数据:
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|
// +---+---+
然后你计算 cube(x, y)
并将计数作为聚合:
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
// +----+----+-----+
与 cube
类似的函数是 rollup
,它从左到右计算层次小计:
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
// +----+----+-----+
只是为了比较让我们看看普通 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
// +---+---+-----+
总结一下:
- 当使用普通
GROUP BY
时,每一行在其对应的摘要中只包含一次。 在
GROUP BY CUBE(..)
中,每一行都包含在它所代表的每个级别组合的摘要中,包括通配符。从逻辑上讲,上面显示的等同于这样的东西(假设我们可以使用NULL
占位符):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
With
GROUP BY ROLLUP(...)
类似于CUBE
,但通过从左到右填充列来分层工作。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
和 CUBE
来自数据仓库扩展,所以如果您想更好地了解它的工作原理,您还可以查看您最喜欢的 RDMBS 的文档。例如 PostgreSQL 在 9.5 和 these are relatively well documented.
- 如果您不想使用 null,请先使用以下示例将其删除 Dfwithoutnull=df.na.drop("all",seq(col name 1,col name 2)) 上面的表达式将删除原始数据帧中的 null
2.group 我猜你知道的。
3.rollup 和 cube 是 GROUPING SET 运算符。 Roll-up是一种多维的聚合处理元素,以层次化的方式
在立方体中,立方体不是按层次处理元素,而是在所有维度上做同样的事情。 你可以尝试grouping_id来理解抽象层次