使用ApacheSpark,使用Java将每个组的前2行变平

使用ApacheSpark,使用Java将每个组的前2行变平,java,mysql,apache-spark,hive,Java,Mysql,Apache Spark,Hive,给出以下输入表: +----+------------+----------+ | id | shop | purchases| +----+------------+----------+ | 1 | 01 | 20 | | 1 | 02 | 31 | | 2 | 03 | 5 | | 1 | 03 | 3 | +----+------------+-----

给出以下输入表:

+----+------------+----------+
| id | shop       | purchases|
+----+------------+----------+
|  1 | 01         |       20 |
|  1 | 02         |       31 |
|  2 | 03         |        5 |
|  1 | 03         |        3 |
+----+------------+----------+
我想根据id和购买情况分组,获得前2家顶级店铺,如下所示:

+----+-------+------+
| id | top_1 | top_2|
+----+-------+------+
|  1 | 02    |   01 |
|  2 | 03    |      |
+----+-------+------+
我使用的是ApacheSpark2.0.1,第一个表是数据集上其他查询和联接的结果。我可以用传统的java在数据集上进行迭代,但我希望有另一种方法使用数据集功能。 我的第一次尝试是:

//dataset is already ordered by id, purchases desc
...
Dataset<Row> ds = dataset.repartition(new Column("id"));
ds.foreachPartition(new ForeachPartitionFunction<Row>() {
        @Override
        public void call(Iterator<Row> itrtr) throws Exception {
            int counter = 0;
            while (itrtr.hasNext()) {
                Row row = itrtr.next();
                if(counter < 2)
                //save it into another Dataset
                counter ++;
            }
        }
    });
//数据集已按id订购,购买说明
...
Dataset ds=Dataset.repartition(新列(“id”);
ds.foreachPartition(新的ForeachPartitionFunction(){
@凌驾
公共无效调用(迭代器itrtr)引发异常{
int计数器=0;
while(itrtr.hasNext()){
行=itrtr.next();
如果(计数器<2)
//将其保存到另一个数据集中
计数器++;
}
}
});

但后来我对如何将其保存到另一个数据集中感到困惑。最后,我的目标是将结果保存到MySQL表中。

使用窗口函数和pivot,您可以定义一个窗口:

import org.apache.spark.sql.expressions.Window
import org.apache.spark.sql.functions.{col, first, row_number}

val w = Window.partitionBy(col("id")).orderBy(col("purchases").desc)
添加
行号
并过滤顶部两行:

val dataset = Seq(
  (1, "01", 20), (1, "02", 31), (2, "03", 5), (1, "03", 3)
).toDF("id", "shop", "purchases")

val topTwo = dataset.withColumn("top", row_number.over(w)).where(col("top") <= 2)
结果是:

+---+---+----+
|id | 1 | 2|
+---+---+----+
|  1| 02|  01|
|2 | 03 |空|
+---+---+----+
我将把把语法转换成Java作为海报的练习(不包括
import static
函数,其余的应该差不多相同)

topTwo.groupBy(col("id")).pivot("top", Seq(1, 2)).agg(first("shop"))