我有一个查询来查找哪个v_address属于哪个v_group,以及何时创建v_address。但是,每个v_group有时都处于活动状态和非活动状态,并且都有日期。因此,我编写了查询以查找这些更改的时间段。
我的问题是我的查询花了很长时间运行,因为它具有多个子查询和联接。
有人有更好的主意来缩短加载数据吗?
我在identifier = 81
下面附加了查询,以进行较小的测试。为了获得最终结果,我将需要检索超过10万个ID的数据。
我试图将内部联接更改为左联接,但是它丢失了空值,并且仍然花费很长时间来检索数据。
with v_address as (
select id, v_group_id, created_at
from prod.venue_address --different schema and table. v_address.v_group_id can have multiple v_address.id
group by 1,2,3
order by 3 asc
),
v_group as (
select identifier, final_status, created_at
from dwh.venue_address_archive
where identifier = 81
group by 1,2,3
order by 3 asc
),
filtering as (
select identifier, created_at,
case when sum(case when final_state = 'active' then 1 else 0 end) > 0 then 'active' else 'inactive' end as filtered_status --This filters either of active or inactive
from v_group
group by 1,2
order by 2 asc
),
prev as (
select identifier, created_at, filtered_status,
lag(case when filtered_status = 'active' then 'active' else 'inactive' end) over (partition by identifier order by created_at) = filtered_status as is_prev_status
from filtering
group by 1,2,3
),
periods as (
select identifier, filtered_status, created_at, is_prev_status,
sum(case when is_prev_status = true then 0 else 1 end) over (order by identifier, created_at) as period
from prev
group by 1,2,3,4
),
islands_gaps_start as (
select identifier, period, min(created_at) as start_at
from periods
group by 2,1
),
islands_gaps as (
select identifier, period, start_at,
lead(start_at) over (partition by identifier order by period) as end_at
from islands_gaps_start
)
select vg.identifier as "vg_id", p.created_at as "vg_created_at", p.filtered_status as "status", p.is_prev_status, p.period, va.id as "va_id", g.start_at, g.end_at
from v_address va
left join v_group vg
on va.venue_id = vg.identifier
inner join filtering f
on vg.identifier = f.identifier
inner join prev pr
on pr.filtered_status = f.filtered_status
inner join periods p
on p.filtered_status = pr.filtered_status
inner join islands_gaps_start gs
on p.period = gs.period
inner join islands_gaps g
on gs.start_at = g.start_at
group by 6,1,2,3,4,5,7,8
order by 2 asc
我已经有了示例identifier = 81
的输出,但是我必须为100k以上的标识符运行该查询,因此,我正在寻找可以缩短查询时间的任何建议。