SQL:单个OVER子句可以支持多个窗口函数吗?

时间:2016-09-29 13:04:28

标签: sql apache-spark-sql spark-dataframe window-functions

假设我有一个网页浏览事件列表,每个事件都有一个会话ID。对于每个事件,我想在该事件的会话中添加按时间顺序排列的第一个页面视图的时间和URL。例如,假设我的事件在表test中,如下所示:

uid | session_id | timestamp | url
----------------------------------------------------
u1    0            0           a.com/
u1    1            1           a.com/p1
u1    1            2           a.com/p2

我想要一个产生以下内容的SQL命令:

uid | session_id | timestamp | url      | s_timestamp | s_url
---------------------------------------------------------------------
u1    0            0           a.com/     0             a.com/
u1    1            1           a.com/p1   1             a.com/p1
u1    1            2           a.com/p2   1             a.com/p1

窗口功能似乎是去这里的方式,但我对它们很陌生。以下语句生成所需的表,但我想知道它是否是次优的

SELECT
    uid,
    session_id,
    timestamp,
    url,
    first_value(url) OVER (PARTITION BY uid, session_id ORDER BY timestamp ASC) s_url,
    first_value(timestamp) OVER (PARTITION BY uid, session_id ORDER BY timestamp ASC) s_timestamp
FROM test

特别是,我两次使用OVER子句似乎是错误的。有没有办法使用单个OVER子句从会话中选择按时间顺序排列的第一个URL和时间戳?我正在使用SPARK SQL,但我会接受任何适用于多个主要SQL系统的答案。

1 个答案:

答案 0 :(得分:3)

可以使用WINDOW关键字命名一个窗口,该窗口随后可以在SELECT子句中引用:

SELECT
    uid,
    session_id,
    timestamp,
    url,
    first_value(url) OVER w s_url,
    first_value(timestamp) OVER w s_timestamp
FROM test
WINDOW w AS (PARTITION BY uid, session_id ORDER BY timestamp ASC)

这适用于Apache Spark SQL和HiveQL。