添加条件到窗口函数

时间:2017-11-30 22:04:05

标签: sql hive

我有以下表格的数据:

page_name   user_id   date_time             input_age   result_age
Page 1      1420356   2017-11-29 09:25:49   65  
Page 1      1516923   2017-11-29 10:47:15               65
Page 1      1518546   2017-11-29 13:16:34   65  
Page 1      1518546   2017-11-29 13:21:26               78
Page 1      1503723   2017-11-29 10:41:57   59  
Page 1      1503723   2017-11-29 10:46:34               59
Page 1      1761217   2017-11-29 15:59:16   65  
Page 1      1761217   2017-11-29 16:01:59   72  
Page 1      1761217   2017-11-29 16:05:59               67
Page 1      1943018   2017-11-29 11:27:14   65
Page 1      1943018   2017-11-29 11:29:52   67
Page 1      2421391   2017-11-29 09:40:41   63  
Page 1      2421391   2017-11-29 09:45:24               63
Page 1      2421391   2017-11-29 09:51:06               59
Page 1      2421391   2017-11-29 10:14:51   63          59
Page 1      2425813   2017-11-29 10:24:26               60
Page 1      2425813   2017-11-29 10:29:14               59

*请注意,数据超过1天且有多个页面。

我要找的是基于每页page_name的user_id级别的最新date_time找到的年龄;如果那时result_age不为null - 取该值(无论input_age是否为null)。如果为null,则取input_age值。 因此,无论时间如何,结果年龄在user_id /页面名称级别都是唯一的。

我知道我们需要类似row_number() over (partition by user_id, page_name order by date_time desc) as row ... where row=1的内容,但我不确定如何添加条件。

示例输出:

page_name   user_id   date_time             input_age   result_age
Page 1      1420356   2017-11-29 09:25:49   65  
Page 1      1516923   2017-11-29 10:47:15               65
Page 1      1518546   2017-11-29 13:21:26               78
Page 1      1503723   2017-11-29 10:46:34               59
Page 1      1761217   2017-11-29 16:05:59               67
Page 1      1943018   2017-11-29 11:29:52   67
Page 1      2421391   2017-11-29 10:14:51               59
Page 1      2425813   2017-11-29 10:29:14               59

感谢您的帮助!

请注意,我的数据位于Hive中,但我认为它与大多数SQL版本的上下文类似。

1 个答案:

答案 0 :(得分:1)

如果你想使用窗口功能来获得最新的记录每x"您通常将查询(包括窗口函数)放在子查询中,然后将条件放在外部查询中:

SELECT * FROM
(
  SELECT 
    *, 
    ROW_NUMBER() OVER(PARTITION BY whatever ORDER BY whateveresle) as rown
  FROM
    joins etc
)a
WHERE 
  rown = 1

如果您有几个日期,并且您想要其中一个,除非它在某种情况下您想要另一个日期,请使用COALESCE(result_age, input_age) - 如果它有值,则给出result_age否则输入年龄。 COALESCE从左到右采用任意数量的参数和作用,让你回到第一个不是空的

最终,我认为您之后的查询将是:

SELECT a.*, COALESCE(a.result_age, a.input_age) as some_age FROM
(
  SELECT 
    table.*, 
    ROW_NUMBER() OVER(PARTITION BY page_name, user_id ORDER BY date_time DESC) as rown
  FROM
    table
)a
WHERE 
  rown = 1