【问题标题】:Merge rows based on a condition根据条件合并行
【发布时间】:2020-07-23 13:45:18
【问题描述】:

是否可以使用 sql 查询根据 Spark SQL 中的条件合并行集合?

如果按顺序排列的两个连续行的purch_dt 之间的差异(line_num)小于5 天,则将它们合并为1 行并输出该合并行,合并行应具有该组的最大值purch_dt。我尝试使用LEAD 函数,但在遇到每个错误条件后我无法将其重置,并将以下行视为一个新组。我无法为每个此类组获得 purch_dt 的最大值。

输入:

orderid | line_num | purch_dt
1 | 1 | 10-02-2020
1 | 2 | 12-02-2020
1 | 3 | 14-02-2020
1 | 4 | 21-03-2020
1 | 5 | 23-03-2020

输出:

orderid | purch_dt
1 | 14-02-2020 -- 1 - 3 combined into 1 row because difference is <5 between each
1 | 23-02-2020 -- 4 - 5 combined into 1 row because difference is <5 between each

Total Output rows = 2 因为我们有2 组。

请注意,line_num 4 用作集合中断,因为它与 line_num = 3 之间的差大于 5。因此它应该有自己的合并记录集。

到目前为止,我有下面的 sql,但我无法突破并创建组。

create temporary view next_dt as
select
order,
LEAD(purch_dt) over (partition by orderid order by line_num asc) AS next_purch_dt,
purch_dt
from orders;

select * 
from (
select 
order,
CASE WHEN datediff(next_purch_dt, purch_dt) < 5 OR next_purch IS NULL THEN 'Y'
ELSE 'N'
END AS flg
from 
next_dt)
WHERE flg = 'Y';

感谢任何帮助。

更新

要求略有变化:-

现在必须在连续记录中的两个不同字段之间进行比较 - 当前记录的 purch_dt 和下一条记录的 return_dt
此外,当输出合并记录组时,purch_dt 应该填充该 line_num 最少的记录的值。 return_dt 列填充了同一组的最大 line_num 记录的值。

输入:

orderid | line_num | purch_dt   | return_dt
1       |    1     | 10-02-2020 | 10-02-2020 
1       |    2     | 12-02-2020 | 13-02-2020
1       |    3     | 14-02-2020 | 14-02-2020
1       |    4     | 21-03-2020 | 23-02-2020
1       |    5     | 23-03-2020 | 24-02-2020

输出:

orderid | purch_dt   | return_dt
1       | 10-02-2020 | 14-02-2020
1       | 21-03-2020 | 24-02-2020

Total Output rows = 2 因为我们有2 组。

请注意,每个输出记录都包含该组中最小为line_num 的记录的purch_dt。并包含return_dt,根据该组中最大line_num 的记录填充。

【问题讨论】:

    标签: apache-spark-sql


    【解决方案1】:

    你几乎明白了,下面的查询对我有用,

    sql("""create temporary view next_dt_orders as
           select * 
                from (
                       select 
                          orderid,line_num,purch_dt,
                          case when datediff( 
                                      (lead(purch_dt) over (partition by orderid order by line_num asc)), 
                                      purch_dt) < 5 
                                     then "N" 
                                     else "Y" 
                               end as flag
                       from 
                          orders) tab
           where
              flag='Y'""")
         
    sql("select * from next_dt_orders").show()  
    
    +-------+--------+----------+----+
    |orderid|line_num|  purch_dt|flag|
    +-------+--------+----------+----+
    |      1|       3|2020-02-14|   Y|
    |      1|       5|2020-03-23|   Y|
    +-------+--------+----------+----+
    

    【讨论】:

    • 感谢您的回复。我已经更新了这个问题,并对要求进行了轻微修改。如何填充中最小line_num记录的purch_dt,并将return_dt填充为该中的最大line_num。如果需要其他信息,请告诉我。
    猜你喜欢
    • 1970-01-01
    • 2020-03-23
    • 1970-01-01
    • 2021-11-21
    • 2021-12-31
    • 2021-06-10
    • 1970-01-01
    • 1970-01-01
    • 2017-05-24
    相关资源
    最近更新 更多