Snowflake 中滑动 Window 函数的解决方法
Workaround on Sliding Window Function in Snowflake
我偶然发现了一个让我非常头疼的问题,如下所示:
我有一个 table 交易,其中包含来自我们的销售 CRM 的关于该实体的信息。我还有一个 table 公司,其中包含有关与这些交易挂钩的公司的信息。
我被要求计算一个名为 Pipeline Conversion Rate 的指标,其计算公式为:
赢得交易/创造交易
到这里,一切都已经很清楚了。然而,在计算这个指标时,我被要求以滑动 window 函数的方式进行,这意味着只计算前 90 天的指标。问题是要查看分子的最后 90 天,我们需要使用一个日期(创建日期);而在查看分母的前 90 天时,我们应该考虑关闭日期(这两个维度都是交易的一部分 table)。
如果我们可以在 Snowflake 中实现这种 window 功能,就不会有任何问题,如下所示(我知道语法可能不完全是这个,但你明白了):
count(deal_id) over (
partition by is_inbound, sales_agent, sales_tier, country
order by created_date range between 90 days preceding and current row
) as created_deals_last_90_days,
count(case when is_deal_won then deal_id end) over (
partition by is_inbound, sales_agent, sales_tier, country
order by created_date range between 90 days preceding and current row
) as won_deals_last_90_days
但据我所知我们不能。所以我目前的解决方法如下(取自):
select
calendar_date,
is_inbound,
sales_tier,
sales_agent,
country,
(
select count(deal_id)
from deals
where d.is_inbound = is_inbound
and d.sales_tier = sales_tier
and d.sales_agent = sales_agent
and d.country = country
and created_date between cal.calendar_date - 90 and cal.calendar_date
) as created_deals_last_90_days,
(
select count(case when is_deal_won then deal_id end)
from deals
where d.is_inbound = is_inbound
and d.sales_tier = sales_tier
and d.sales_agent = sales_agent
and d.country = country
and closed_date between cal.calendar_date - 90 and cal.calendar_date
) as won_deals_last_90_days
from calendar as cal
left join deals as d on cal.calendar_date between d.created_date and d.closed_date
*请注意,我在这里使用 calendar table
作为基数 table,以便查看所有日历日期,因为如果没有它,我可能会说我会错过那些日期没有新的交易(可能在周末发生)。
问题是当我交叉检查原始数据和这个查询的输出时,我没有得到正确的数字,我不知道如何使这个(丑陋的)解决方法,嗯......工作。
欢迎任何想法!
好吧,事实证明它比我预期的要容易得多。经过一些 trial-and-error,我发现唯一可能失败的是外部查询中的 JOIN 条件:
on cal.calendar_date between d.created_date and d.closed_date
这是假设两个日期都需要在范围内,但这个假设是错误的。通过将外部查询的上述部分调整为:
on cal.calendar_date >= d.created_date
它捕获在 calendar_date
或之前创建的所有交易,因此所有这些交易都是必填字段。
保持查询的其余部分不变,并假设任何分区中都没有空值,结果就是我预期的结果。
我偶然发现了一个让我非常头疼的问题,如下所示:
我有一个 table 交易,其中包含来自我们的销售 CRM 的关于该实体的信息。我还有一个 table 公司,其中包含有关与这些交易挂钩的公司的信息。
我被要求计算一个名为 Pipeline Conversion Rate 的指标,其计算公式为: 赢得交易/创造交易
到这里,一切都已经很清楚了。然而,在计算这个指标时,我被要求以滑动 window 函数的方式进行,这意味着只计算前 90 天的指标。问题是要查看分子的最后 90 天,我们需要使用一个日期(创建日期);而在查看分母的前 90 天时,我们应该考虑关闭日期(这两个维度都是交易的一部分 table)。
如果我们可以在 Snowflake 中实现这种 window 功能,就不会有任何问题,如下所示(我知道语法可能不完全是这个,但你明白了):
count(deal_id) over (
partition by is_inbound, sales_agent, sales_tier, country
order by created_date range between 90 days preceding and current row
) as created_deals_last_90_days,
count(case when is_deal_won then deal_id end) over (
partition by is_inbound, sales_agent, sales_tier, country
order by created_date range between 90 days preceding and current row
) as won_deals_last_90_days
但据我所知我们不能。所以我目前的解决方法如下(取自
select
calendar_date,
is_inbound,
sales_tier,
sales_agent,
country,
(
select count(deal_id)
from deals
where d.is_inbound = is_inbound
and d.sales_tier = sales_tier
and d.sales_agent = sales_agent
and d.country = country
and created_date between cal.calendar_date - 90 and cal.calendar_date
) as created_deals_last_90_days,
(
select count(case when is_deal_won then deal_id end)
from deals
where d.is_inbound = is_inbound
and d.sales_tier = sales_tier
and d.sales_agent = sales_agent
and d.country = country
and closed_date between cal.calendar_date - 90 and cal.calendar_date
) as won_deals_last_90_days
from calendar as cal
left join deals as d on cal.calendar_date between d.created_date and d.closed_date
*请注意,我在这里使用 calendar table
作为基数 table,以便查看所有日历日期,因为如果没有它,我可能会说我会错过那些日期没有新的交易(可能在周末发生)。
问题是当我交叉检查原始数据和这个查询的输出时,我没有得到正确的数字,我不知道如何使这个(丑陋的)解决方法,嗯......工作。
欢迎任何想法!
好吧,事实证明它比我预期的要容易得多。经过一些 trial-and-error,我发现唯一可能失败的是外部查询中的 JOIN 条件:
on cal.calendar_date between d.created_date and d.closed_date
这是假设两个日期都需要在范围内,但这个假设是错误的。通过将外部查询的上述部分调整为:
on cal.calendar_date >= d.created_date
它捕获在 calendar_date
或之前创建的所有交易,因此所有这些交易都是必填字段。
保持查询的其余部分不变,并假设任何分区中都没有空值,结果就是我预期的结果。