使用 CASE WHEN 子句的百分比差异

Percentage Difference Using CASE WHEN clause

我正在使用的 table 叫做 'transactions'。这些列是 id(客户 ID)、amount(客户花费的金额)、timestamp(购买时间)。

我正在尝试查询:

样本数据

id amount timestamp
1 50 2021-12-01
2 60 2021-12-02
3 70 2021-11-05
4 80 2022-01-26
5 90 2022-01-25
6 20 2022-01-26
7 80 2022-01-19

预期输出

yesterday_revenue pct_change_week_ago mtd pct_change_month_prior
100 0.25 270 0.50

这是我的代码。百分比变化列都不正确。请帮忙

select

-- yesterday
sum(case when timestamp::date = current_date - 1 then amount else null end) yesterday_revenue,

-- yesterday v. last week
(sum(case when timestamp::date > current_date - 1 then amount else null end) - sum(case when timestamp::date = current_date - 8 then amount else null end))
/ sum(case when timestamp::date = current_date - 8 then amount else null end) pct_change_week_ago,

-- mtd
sum(case when date_trunc('month',timestamp) = date_trunc('month',CURRENT_DATE -1) then amount else null end) mtd,

-- mtd v. month prior
(sum(case when date_trunc('month',timestamp) = date_trunc('month',CURRENT_DATE -1) then amount else null end) - sum(case when date_trunc('month',timestamp) = date_trunc('month',CURRENT_DATE -1) - interval '1 month'
      and date_part('day',timestamp ) <= date_part('day', CURRENT_DATE -1) then amount else null end))
    / sum(case when date_trunc('month',timestamp) = date_trunc('month',CURRENT_DATE -1) - interval '1 month'
      and date_part('day',timestamp ) <= date_part('day', CURRENT_DATE -1) then amount else null end) pct_change_month_prior

from transactions

好的,真的,这是关于你陈述的 SELECT 部分的数学。

更改的金额是:new - old

乘数为(new - old) / oldnew / old - 1

作为百分比,您需要乘以 100...100 * (new / old - 1) 但我知道您并不担心这个。

此外,让我们确保您的新旧版本正确无误。

昨天的总和:

sum(case when timestamp::date = CURRENT_DATE - 1 then amount else null end)

8 天前总数:

sum(case when timestamp::date = CURRENT_DATE - 8 then amount else null end)

1 个月到昨天总和:

sum(case when timestamp::date > CURRENT_DATE - 1 - INTERVAL '1 month' AND timestamp::date <= CURRENT_DATE - 1 then amount else null end)

1个月至1个月零1天前总和:

sum(case when timestamp::date > CURRENT_DATE - 1 - INTERVAL '2 month' AND timestamp::date <= CURRENT_DATE - 1 - INTERVAL '1 month' then amount else null end)

月初到昨天总和:

sum(case when timestamp::date > DATE_TRUNC('month', CURRENT_DATE - 1) AND timestamp::date <= CURRENT_DATE - 1 then amount else null end)

昨天上个月开始到一个月前昨天的总和:

sum(case when timestamp::date > DATE_TRUNC('month', CURRENT_DATE - 1 - INTERVAL '1 month') AND timestamp::date <= CURRENT_DATE - 1 - INTERVAL '1 month' then amount else null end)

重要的是您不要将 = 更改为 > 或裁剪到日期部分,否则您将包含比您真正想要的更多的内容。

实际上,通过裁剪到月份部分,它几乎总是会总结两个月的所有交易。

需要考虑的一些事项:

  • “昨天与上周对比”目前在开头使用 timestamp::date > current_date - 1。这将只包括今天的交易,而不是昨天的交易(它说“比昨天大”)。我觉得应该是timestamp::date = current_date - 1
  • 我在这里可能是错的,但我认为 sum(case when date_trunc('month',timestamp) = date_trunc('month',CURRENT_DATE -1) 也会捕获当前日期的交易,如果当前日期与昨天在同一个月的话。你可能不想要那个。
  • 据我所知,'pct_change_month_prior'应该是1.45,而不是0.5。您在 12 月有 110,在 1 月有 270270 - 110 = 160160 / 110 = 1.45。您现有的查询已经 returns 结果。 FWIW,您也可以使用 new/old-1 以更简单的方式获得相同的结果。