如何使用具有两列的 Hive sql 滞后函数?

Posted

技术标签:

【中文标题】如何使用具有两列的 Hive sql 滞后函数?【英文标题】:How to use Hive sql's lag function with two columns? 【发布时间】: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 子句还是有更好的方法?

【问题讨论】:

【参考方案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

【讨论】:

以上是关于如何使用具有两列的 Hive sql 滞后函数?的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server:在具有两列的表上进行无聚合的旋转

如何检索表的值以获取sql中两列的最大值

如何使用聚合 MongoDB 查找具有两列的不同字段

Hive:如何比较 WHERE 子句中具有复杂数据类型的两列?

如何设置具有两列的组合框的值?

如何使用 VBA 在 Excel 宏中删除具有两列的重复项?