在非常大的 table 中每个组的有效 select 最新行?
Effectively select latest row for each group in a very large table?
我有(例如)一个 table Users (user_id, status, timestamp, ...)
.
我还有一个tableSpecialUsers (user_id, ...)
.
我需要显示每个特殊用户的最新状态。
问题是 Users
table 非常非常大(超过 50 亿 行)。例如 this question 中的大多数解决方案只是挂起或出现“磁盘已满”错误。
SpecialUsers
table 小得多——“只有”60 万行。
不支持 SELECT DISTINCT ON()
。在 Amazon RedShift 上工作。
编辑:每个请求查看失败的尝试 - 其中一个导致磁盘已满错误是这样的:
with users_with_status (user_id, status, timestamp)
as (
select su.user_id, u.instance_type, u.timestamp
from specialusers su
join users u on su.user_id = u.user_id
)
select l.instance_id, l.instance_type
from users_with_status l
left outer join users_with_status r
on l.user_id = r.user_id and l.timestamp < r.timestamp
where r.timestamp is null;
我知道我正在加入一个 bug table 本身,但希望第一次加入小 table 会减少处理的行数。
无论如何,window 函数似乎是这里的解决方案。
也许 join
和 window 函数可以工作:
select su.*
from (select s.user_id, u.status, u.timestamp,
max(u.timestamp) over (partition by s.user_id) as max_timestamp
from specialusers s join
users u
on s.user_id = u.user_id
) su
where timestamp = max_timestamp;
这里专门使用 max()
而不是 row_number()
,因为推测它可能会使用更少的资源。
我有(例如)一个 table Users (user_id, status, timestamp, ...)
.
我还有一个tableSpecialUsers (user_id, ...)
.
我需要显示每个特殊用户的最新状态。
问题是 Users
table 非常非常大(超过 50 亿 行)。例如 this question 中的大多数解决方案只是挂起或出现“磁盘已满”错误。
SpecialUsers
table 小得多——“只有”60 万行。
SELECT DISTINCT ON()
。在 Amazon RedShift 上工作。
编辑:每个请求查看失败的尝试 - 其中一个导致磁盘已满错误是这样的:
with users_with_status (user_id, status, timestamp)
as (
select su.user_id, u.instance_type, u.timestamp
from specialusers su
join users u on su.user_id = u.user_id
)
select l.instance_id, l.instance_type
from users_with_status l
left outer join users_with_status r
on l.user_id = r.user_id and l.timestamp < r.timestamp
where r.timestamp is null;
我知道我正在加入一个 bug table 本身,但希望第一次加入小 table 会减少处理的行数。
无论如何,window 函数似乎是这里的解决方案。
也许 join
和 window 函数可以工作:
select su.*
from (select s.user_id, u.status, u.timestamp,
max(u.timestamp) over (partition by s.user_id) as max_timestamp
from specialusers s join
users u
on s.user_id = u.user_id
) su
where timestamp = max_timestamp;
这里专门使用 max()
而不是 row_number()
,因为推测它可能会使用更少的资源。