每个用户 ID 的 first_value 和 last_value

Posted

技术标签:

【中文标题】每个用户 ID 的 first_value 和 last_value【英文标题】:first_value and last_value for each user id 【发布时间】:2018-10-26 13:14:26 【问题描述】:

我正在尝试获取我的 scheduled_jobs 表中每个用户的第一个预定开始时间和最后一个预定结束时间。

我可以让它为一个用户工作,但是当我每天为所有用户尝试时,我可以获得最后一次,但是第一次显示所有 user_id 的第一个 user_id 的时间时无法获得正确的时间。

这是我的代码:

SELECT DISTINCT on (user_id)
    user_id, first_value(scheduled_jobs.at) over (order by user_id, scheduled_jobs.at ASC),
    last_value(scheduled_jobs.to) over (order by user_id, scheduled_jobs.at DESC)
FROM scheduled_jobs
WHERE scheduled_jobs.at between CURRENT_DATE+INTERVAL'3 day' and CURRENT_DATE +INTERVAL '4 day'

当前结果示例:

user_id | first_value         | last_value
  19    | 2018-10-29 07:00:00 | 2018-10-29 17:00:00
  30    | 2018-10-29 07:00:00 | 2018-10-29 15:00:00
  37    | 2018-10-29 07:00:00 | 2018-10-29 16:30:00 

每个 user_id 的 Last_value 显示正确,但 first_value 始终显示所有 user_id 的第一个值。

我尝试使用 JOIN 和 USING 查询将它们拆分为不同的 SELECT 查询,但对于 first_value 仍然得到不正确的结果。

【问题讨论】:

【参考方案1】:

您需要一个PARTITION BY 子句,它会根据user_id 生成帧

SELECT DISTINCT on (user_id)
    user_id, 
    first_value(sj.at) OVER (PARTITION BY user_id ORDER BY sj.at ASC),
    last_value(sj.to) OVER (PARTITION BY user_id ORDER BY sj.at DESC)
FROM 
    scheduled_jobs sj
WHERE 
    sj.at BETWEEN CURRENT_DATE + 3 and CURRENT_DATE + 4

另外:请谨慎使用last_value。有时它不会按预期工作。 See here

您应该使用first_valueDESC 来代替:

first_value(scheduled_jobs.at) over (partition by user_id order by scheduled_jobs.at DESC)

【讨论】:

是的,这通过添加分区解决了我的问题,就像上面的答案一样【参考方案2】:

为什么不简单地使用min()max()?由于您没有选择任何其他列,因此不需要以 distinct on() 或窗口函数开头:

SELECT user_id, 
       min(scheduled_jobs.at),
       max(scheduled_jobs.at)
FROM scheduled_jobs
WHERE scheduled_jobs.at between CURRENT_DATE + 3 and CURRENT_DATE + 4
group by user_id;

当您想将天数添加到 DATE 值时,您不需要使用 interval,只需添加一个整数即可

【讨论】:

是的,这解决了我的问题,也许我把它复杂化了。下面的答案也有效。不过,它只能让我将一个标记为已接受的答案。

以上是关于每个用户 ID 的 first_value 和 last_value的主要内容,如果未能解决你的问题,请参考以下文章

OVER 函数和 first_value

Oracle分析函数-first_value()和last_value()

Oracle分析函数-first_value()和last_value()

Oracle分析函数-first_value()和last_value()

FIRST_VALUE 窗口函数 - 查询执行期间超出资源

Apache spark - 窗口函数,FIRST_VALUE 不起作用