【问题标题】:How to use Hive sql's lag function with two columns?如何使用具有两列的 Hive sql 滞后函数?
【发布时间】:2017-12-06 03:41:56
【问题描述】:

我觉得我有一个相当简单的SQL问题要解决,只是不知道如何正确搜索。

假设我有一个表,其中值根据时间更新:

|timestamp|value|session|
|---------|-----|-------|
| ts1     | v1  |  s1   |
| ts2     | v2  |  s1   |
| ts3     | v3  |  s1   |
| ...     | ..  |  s2   |

我想获取当前值和以前的值以及相关的时间戳

所以结果应该是:

|timestamp_current|value_current|timestamp_prev|value_prev|
|-----------------|-------------|--------------|----------|
|      ts2        |      v2     |    ts1       |    v1    |
|      ts3        |      v3     |    ts2       |    v2    |
|      ...        |      ..     |    ...       |    ..    |

如果我只是想获取前一个值而不是前一个时间戳,我认为以下查询是正确的:

select timestamp, value, lag(value,1) over (partition by (session) order by timestamp) from mytable

但是,从上一行添加两个值的正确方法是什么,我是添加两个 lag 子句还是有更好的方法?

【问题讨论】:

    标签: sql hive lag window-functions


    【解决方案1】:

    您可以通过使用lag() 两次来得出结果;一次用于prev_timestamp,一次用于prev_val,如下所示。

    select * from
    (
    select timestamp, 
           value, 
           lag(timestamp) over(partition by session order by timestamp) as prev_timestamp, 
           lag(value) over(partition by session order by timestamp) as prev_value
    from table1
    ) t
    where prev_timestamp is not null
    

    where 子句用于排除具有prev_timestampNULL 的行

    结果:

    +-----------+-------+----------------+------------+
    | timestamp | value | prev_timestamp | prev_value |
    +-----------+-------+----------------+------------+
    | ts2       | v2    | ts1            | v1         |
    | ts3       | v3    | ts2            | v2         |
    +-----------+-------+----------------+------------+
    

    DEMO

    【讨论】:

      【解决方案2】:

      实现此目的的另一种方法是使用 row_number 函数并连接记录,如下所示。但在同一查询中使用两个滞后方法很可能比 row_number 和左连接方法更高效。

      WITH dt AS (SELECT  timestamp, value, ROW_NUMBER() OVER(PARTITION BY session ORDER BY timestamp) as row_num FROM table1)
      SELECT 
        t0.timestamp, 
        t0.value, 
        t1.timestamp as prev_timestamp,
        t1.value as prev_value
      FROM dt t0 
      LEFT OUTER JOIN dt t1
      ON t0.row_num = t1.row_num - 1
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-03-03
        • 1970-01-01
        • 2015-02-16
        • 2017-04-30
        相关资源
        最近更新 更多