【问题标题】:How to get write in spark and hive query for below case如何在以下情况下写入 spark 和 hive 查询
【发布时间】:2019-02-10 06:31:52
【问题描述】:

我的数据是:

User id     product_id    action

1                apple             incart
1                 apple            purchased 
1                 banana         incart
2                 banana         incart
2                 banana         purchased
3                 carrot            incart

我需要作为 user_id 和 product_id 的输出,其操作只有 incart 而没有购买。

【问题讨论】:

  • 同时指定预期结果。并向我们​​展示您当前的代码尝试。
  • 我是 spark 和 hive 的初学者。我需要解决这个问题的方法。输出应显示 user_id 和 product_id,其中 action = incart 且不等于购买。
  • 你有 RDD 吗?一个DF?请尝试更具体,并向我们展示您的尝试。
  • @pheeleeppoo 使用 RDD 或 DF 什么都可以。我只需要解决问题的方法。我知道我需要在 user_id 和 product_id 上使用 groupby,但是如何只找到那些有 action= incart 和 action != purchase 记录的 user_id 和 product_id
  • @RupeshMalkar 请立即查看

标签: sql apache-spark hadoop hive


【解决方案1】:
val df1 = df.filter(col("action") === "purchased")
val df2 = df.filter(col("action") === "incart")
df2.join(df1,df2.col("User_id") === df1.col("User_id") && df2.col("product_id") === df1.col("product_id"),"leftanti").drop("action").show

【讨论】:

    【解决方案2】:

    假设你有这样的 DF:

    +-------+----------+----------+
    |User_id|product_id|    action|
    +-------+----------+----------+
    |      1|     apple|    incart|
    |      1|     apple|purchased |
    |      1|    banana|    incart|
    |      2|    banana|    incart|
    |      2|    banana| purchased|
    |      3|    carrot|    incart|
    +-------+----------+----------+
    

    一种方法可以应用 groupBy 来创建一个包含所有操作的新字段,然后按您想要的条件进行过滤。

    val output = df.groupBy("User_id","product_id").agg(collect_list("action").as("set"))
    

    然后根据您想要的条件进行过滤。在这种情况下:

    output.where(array_contains($"set", "incart").and(!array_contains($"set", "purchased"))).select("User_id","product_id").show()
    

    将产生预期的输出:

    +-------+----------+
    |User_id|product_id|
    +-------+----------+
    |      3|    carrot|
    |      1|    banana|
    +-------+----------+
    

    【讨论】:

      【解决方案3】:

      您可以在HIVE 中使用NOT EXISTS

      SELECT t.userid, t.product_id 
      FROM table t
      WHERE action = 'incart' AND
            NOT EXISTS (SELECT 1 
                        FROM table t1 
                        WHERE t1.userid = t.userid and 
                              t1.product_id = t.product_id and 
                              t1.action = 'purchased'
                       );
      

      【讨论】:

        【解决方案4】:

        使用简单聚合+case:

        SELECT t.userid, t.product_id
        FROM
        (
        SELECT t.userid, t.product_id, 
               max(case when t.action = 'purchased' then 1 else 0 end) has_purchased,
               max(case when t.action = 'incart'    then 1 else 0 end) has_incart
        FROM table t
        GROUP BY t.userid, t.product_id
        ) s
        WHERE has_purchased=0 and has_incart=1;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-06-27
          • 1970-01-01
          • 2022-01-03
          • 2023-03-31
          • 1970-01-01
          • 1970-01-01
          • 2020-07-05
          • 1970-01-01
          相关资源
          最近更新 更多