spark sql:计算具有不同谓词的出现

时间:2018-07-28 13:13:52

标签: sql apache-spark apache-spark-sql

让我们说我有这样的数据

| department | user  | purchases |
|:-----------|------:|:---------:|
| sport      | user1 |     1     |
| video      | user1 |     7     |
| audio      | user2 |     5     |
| book       | user2 |     3     |
| sport      | user2 |     8     |

,依此类推。我需要像这样在每个类别中进行大量购买:

| department | users5  | users7  |  users16 |
|:-----------|--------:|:-------:|:--------:|
| sport      | 10      |   5     |     3    |
| video      | 7       |   6     |     4    |
| audio      | 3       |   1     |     0    |
| book       | 5       |   1     |     0    |

users5-在该部门购买了<= 5个产品的用户数

users7-在该部门购买了5到7笔商品的用户数

users16-在该部门中进行7到16次购买的用户数

我可以通过以下方法实现目标:(火花sql伪代码)

val users5 = df.filter("purchases" < 5).groupby("category").agg(count("user"))
val users7 = df.filter("purchases" >= 5 AND "purchases" < 7).groupby("category").agg(count("user"))
val users16 = df.filter("purchases" >= 7 AND "purchases" < 16).groupby("category").agg(count("user"))
users5.join(users7, Seq("category"), "outer").join(users16, Seq("category"), "outer")

我的问题是,有没有更普遍的明确方法来完成相同的工作? 我正在使用Apache Spark 2.3

2 个答案:

答案 0 :(得分:1)

一个带有SQL查询的选项。

val res=spark.sql("""
                  select category
                        ,count(case when purchases<=5 then user end) as users5
                        ,count(case when purchases>5 and purchases<7 then user end) as users7
                        ,count(case when purchases>=7 and purchases<16 then user end) as users16
                  from df
                  group by category
                  """
                 )

答案 1 :(得分:1)

如果您要使用api方式,则以下是解决方法

import org.apache.spark.sql.functions._
df.groupBy("category").agg(sum(when(col("purchases") < 5, 1).otherwise(0)).as("users5"),
  sum(when(col("purchases") >= 5 && col("purchases") < 7, 1).otherwise(0)).as("users7"),
  sum(when(col("purchases") >= 7 && col("purchases") < 16, 1).otherwise(0)).as("users16"))
  .show(false)