在 Hive 中使用 case 语句填充前面的值

Populate preceding value using case statement in Hive

我在 Hive table 中有一列 event,如下所示。

Event

Sent
Sent
Open
Open
Click
Sent
Open
Signup
Sent
Open
Click

现在我想使用 case 语句基于 event 列中的值创建新列。

我想在事件列中有 signup 的地方我希望 Previous_event 列正好是 preceding 值。

我试过如下。

select event, 
       case when event = 'Sent' then 'No_event' 
            when event = 'Open' then 'Sent' 
            when event = 'Click' then 'Open'  
            else -1 
       end as Previous_event 
from table;

Result

Sent    No_event
Sent    No_event
Open    Sent
Open    Sent
Click   Open
Sent    No_event
Open    Sent
Signup  -1
Sent    No_event
Open    Sent
Click   Open

Expected result

Sent    No_event
Sent    No_event
Open    Sent
Open    Sent
Click   Open
Sent    No_event
Open    Sent
Signup  Open
Sent    No_event
Open    Sent
Click   Open

我怎样才能达到我想要的?

使用相关子查询。

基于,您可以尝试以下查询(for MySQL):

select t1.event, 
       case when t1.event = 'Sent' then 'No_event' 
            when t1.event = 'Open' then 'Sent' 
            when t1.event = 'Click' then 'Open' 
            when t1.event = 'Signup' then (select t2.event 
                                           from table as t2 
                                           where t2.eventdate < t1.eventdate 
                                           order by t2.eventdate desc 
                                           limit 1)         
            else -1 
       end as Previous_event 
from table as t1;

以下是包含类似 Problem/Solution 的 URL:

Hive access previous row value

https://community.hortonworks.com/questions/39533/fill-null-with-previous-row-values-in-hive.html

SQL 将是:

select event, prev_event(event) as Previous_event from table;

UDF 代码:

    import org.apache.hadoop.hive.ql.exec.UDF;

    public class cum_mul extends UDF  {
    private String prevValue = null;

    public String evaluate(String value) {

    switch(value) 
        { 
            case "Sent": 
        prevValue = "No_event";
                return "No_event"; 
            case "Open": 
        prevValue = "Sent";
                return "Sent";  
            case "Click": 
        prevValue = "Open";
                return "Open"; 
            default: 
                return prevValue; 
        } 
      }
}