使用 Amazon Redshift / PostgreSQL 进行漏斗查询
Posted
技术标签:
【中文标题】使用 Amazon Redshift / PostgreSQL 进行漏斗查询【英文标题】:Funnel query with Amazon Redshift / PostgreSQL 【发布时间】:2015-06-07 14:29:48 【问题描述】:我正在尝试使用 Redshift 中的事件数据分析漏斗,但很难找到有效的查询来提取该数据。
例如,在 Redshift 中我有:
timestamp action user id
--------- ------ -------
2015-05-05 12:00 homepage 1
2015-05-05 12:01 product page 1
2015-05-05 12:02 homepage 2
2015-05-05 12:03 checkout 1
我想提取漏斗统计信息。例如:
homepage_count product_page_count checkout_count
-------------- ------------------ --------------
100 50 25
其中homepage_count
代表访问主页的不同用户数,product_page_count
代表访问主页之后访问主页的不同用户数量,checkout_count
代表数量在访问主页和产品页面后结帐的用户。
使用 Amazon Redshift 实现这一目标的最佳查询是什么?是否可以使用单个查询?
【问题讨论】:
【参考方案1】:我认为最好的方法可能是为每个用户的每种类型的首次访问添加标志到数据中,然后将这些标志用于聚合逻辑:
select sum(case when ts_homepage is not null then 1 else 0 end) as homepage_count,
sum(case when ts_productpage > ts_homepage then 1 else 0 end) as productpage_count,
sum(case when ts_checkout > ts.productpage and ts.productpage > ts.homepage then 1 else 0 end) as checkout_count
from (select userid,
min(case when action = 'homepage' then timestamp end) as ts_homepage,
min(case when action = 'product page' then timestamp end) as ts_productpage,
min(case when action = 'checkout' then timestamp end) as ts_checkout
from table t
group by userid
) t
【讨论】:
是否也包括访问产品页面后结帐但访问主页后结帐的情况? 最后一个条件不应该是case when ts_checkout > ts_productpage and ts_productpage> ts_homepage then 1 else 0 end
吗?
@lta 。 . .现在可以了。 ;)
我还发布了一个关于保留表的类似问题。 ***.com/questions/30698175/…
@Gordon Linoff 你能解释一下它是如何涵盖@Ita 描述的所有情况的吗?【参考方案2】:
上面的答案非常正确。我已经为将它用于 AWS Mobile Analytics 和 Redshift 的人进行了修改。
select sum(case when ts_homepage is not null then 1 else 0 end) as homepage_count,
sum(case when ts_productpage > ts_homepage then 1 else 0 end) as productpage_count,
sum(case when ts_checkout > ts_productpage and ts_productpage > ts_homepage then 1 else 0 end) as checkout_count
from (select client_id,
min(case when event_type = 'App Launch' then event_timestamp end) as ts_homepage,
min(case when event_type = 'SignUp Success' then event_timestamp end) as ts_productpage,
min(case when event_type = 'Start Quiz' then event_timestamp end) as ts_checkout
from awsma.v_event
group by client_id
) ts;
【讨论】:
【参考方案3】:以防万一需要更精确的模型:产品页面可以打开两次。第一次在主页之前,第二次在主页之后。这种情况通常也应视为转换。
Redshift SQL 查询:
SELECT
COUNT(
DISTINCT CASE WHEN cur_homepage_time IS NOT NULL
THEN user_id END
) Step1,
COUNT(
DISTINCT CASE WHEN cur_homepage_time IS NOT NULL AND cur_productpage_time IS NOT NULL
THEN user_id END
) Step2,
COUNT(
DISTINCT CASE WHEN
cur_homepage_time IS NOT NULL AND cur_productpage_time IS NOT NULL AND cur_checkout_time IS NOT NULL
THEN user_id END
) Step3
FROM (
SELECT
user_id,
timestamp,
COALESCE(homepage_time,
LAG(homepage_time) IGNORE NULLS OVER(PARTITION BY user_id
ORDER BY time)
) cur_homepage_time,
COALESCE(productpage_time,
LAG(productpage_time) IGNORE NULLS OVER(PARTITION BY distinct_id
ORDER BY time)
) cur_productpage_time,
COALESCE(checkout_time,
LAG(checkout_time) IGNORE NULLS OVER(PARTITION BY distinct_id
ORDER BY time)
) cur_checkout_time
FROM
(
SELECT
timestamp,
user_id,
(CASE WHEN event = 'homepage'
THEN timestamp END) homepage_time,
(CASE WHEN event = 'product page'
THEN timestamp END) productpage_time,
(CASE WHEN event = 'checkout'
THEN timestamp END) checkout_time
FROM events
WHERE timestamp > '2016-05-01' AND timestamp < '2017-01-01'
ORDER BY user_id, timestamp
) event_times
ORDER BY user_id, timestamp
) event_windows
此查询使用事件发生的最近时间戳填充每一行的cur_homepage_time
、cur_productpage_time
和cur_checkout_time
。因此,如果发生特定时间(读取行)事件,则特定列不是NULL
。
更多信息here。
【讨论】:
以上是关于使用 Amazon Redshift / PostgreSQL 进行漏斗查询的主要内容,如果未能解决你的问题,请参考以下文章
不使用 jdbc 驱动程序查询 Amazon Redshift
使用 Amazon Redshift / PostgreSQL 进行队列分析