SQL和Spark的新手,我试图在包含不同计数的数据集上添加一列。 数据集:
| col1 | col2 |
| A | B |
| C | D |
| A | B |
| A | B |
所需结果:
| col1 | col2 | uniques |
| A | B | 3 |
| C | D | 1 |
我的Java代码:
return dataset.agg(countDistinct(col1,col2));
但是没有效果
答案 0 :(得分:1)
区别不适用于此处。在计数之前,对每组中的不同 remove 重复项进行计数,因此“唯一性”列始终将仅包含一个。
要获得所需的结果,您需要执行基本的分组/聚合操作。以下是实现它的方法:
SparkSession spark = ...;
StructType schema = new StructType(new StructField[]{
new StructField("col1", DataTypes.StringType, true, new MetadataBuilder().build()),
new StructField("col2", DataTypes.StringType, true, new MetadataBuilder().build())
});
List<Row> rows = new ArrayList<>();
rows.add(RowFactory.create("A", "B"));
rows.add(RowFactory.create("C", "D"));
rows.add(RowFactory.create("A", "B"));
rows.add(RowFactory.create("A", "B"));
Dataset<Row> ds = spark.createDataFrame(rows, schema);
ds.createTempView("table");
// (1)
spark.sql("select col1, col2, count(*) as uniques from table group by col1, col2").show();
// (2)
ds.groupBy(ds.col("col1"), ds.col("col2")).count().show();
// (3)
ds.groupBy(ds.col("col1"), ds.col("col2"))
.agg(functions.count(functions.lit(1)).alias("uniques") /*, functions.avg(...), functions.sum(...) */)
.show();
第一个示例是所谓的“ Spark SQL”。
(2)和(3)的语法可能很难理解。我将尝试用非常基本的术语来解释它们。 groupBy
(逻辑上)将数据分组为类似Map<GroupKey, List<Row>>
的数据。 count
将计数聚合函数应用于每个组(此函数的结果是新列),然后“扔掉” List<Row>
。因此,在结果中,我们有一个表,该表由“ col1”,“ col2”(由于它们是分组键而被自动添加)和新列“ uniques”组成。
有时您需要同时应用多个聚合函数。第三个例子解决了这个问题。您可以在agg
中列出多个功能。每个此类函数都会产生一个新列。