一个选项使用相关的子查询。假设您的用户/日期表名为
我有一个名为event_user_fav_color_changed
的表。表中的每一行都表示用户更改其喜爱的颜色的事件对于特定范围内的每个日期,我希望获得每个用户自该日期起最喜欢的颜色
以下是event_user_fav_color_changed
表格示例:
user_id date updated_at_datetime fav_color
1234 2020-01-01 2020-01-01 12:00:03 blue
1234 2020-01-05 2020-01-05 10:30:00 green
以下是我感兴趣的用户和日期的示例表:
user_id date
1234 2020-01-01
1234 2020-01-04
1234 2020-01-05
1234 2020-01-06
以下是所需的输出:
user_id date fav_color
1234 2020-01-01 blue
1234 2020-01-04 blue
1234 2020-01-05 green
1234 2020-01-06 green
data
,那么您将执行以下操作:
select
d.*,
(
select e.fav_color
from event_user_fav_color_changed e
where e.user_id = d.user_id and e.date <= d.date
order by e.date desc limit 1
)
from data d
您可以使用row_number()
窗口函数
select * from
(
select user_id, date, updated_at_datetime, fav_color,
row_number() over(partition by user_id,date order by updated_at_datetime desc) as rn
from tablename
)A where rn=1
听起来您不能将查找限制在任何特定范围内。因此,基本上每一行都必须搜索更新的最后一次出现。
select d.date,
(
select first_value(fav_color) over (order by updated_at_datetime desc)
from event_user_fav_color_changed
where updated_at_datetime < d.date
) as fav_as_of
from dates d
我对普雷斯托一无所知,但我相信这个问题应该有效。
表示这一点的一种方法是使用联接和row_number()
:
select uc.*
from (select ufcc.*,
row_number() over (partition by ufcc.user_id order by ufcc.date desc) as seqnum
from user_dates ud join
event_user_fav_color_changed ufcc
on ud.user_id = ufcc.user_id and
ud.date > ufcc.date
) uc
where seqnum = 1;
如果有很多颜色变化,这可能是低效的。使用lead()
的联接可能更高效:
select ufcc.*
from user_dates ud join
(select ufcc.*,
lead(ufcc.date) over (partition by ufcc.user_id order by ufcc.date) as next_date
from event_user_fav_color_changed ufcc
) ufcc
on ud.user_id = ufcc.user_id and
ud.date > ufcc.date and
(ud.date <= ufcc.next_date or ufcc.next_date is null);
或横向连接:
select ufcc.*
from user_dates ud cross join lateral
(select ufcc.*
from event_user_fav_color_changed ufcc
where ud.user_id = ufcc.user_id and
ud.date > ufcc.date
order by ufcc.date desc
limit 1
) ud