使用 CASE WHEN 子句的百分比差异
Percentage Difference Using CASE WHEN clause
我正在使用的 table 叫做 'transactions'。这些列是 id(客户 ID)、amount(客户花费的金额)、timestamp(购买时间)。
我正在尝试查询:
- 昨日收入:金额之和。
- 8 天前收入与昨天收入的百分比差异。
- MTD.
- 上个月 MTD 与本月 MTD 的百分比差异。
样本数据
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) / old
或new / 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 月有 270
。 270 - 110 = 160
和 160 / 110 = 1.45
。您现有的查询已经 returns 结果。 FWIW,您也可以使用 new/old-1
以更简单的方式获得相同的结果。
我正在使用的 table 叫做 'transactions'。这些列是 id(客户 ID)、amount(客户花费的金额)、timestamp(购买时间)。
我正在尝试查询:
- 昨日收入:金额之和。
- 8 天前收入与昨天收入的百分比差异。
- MTD.
- 上个月 MTD 与本月 MTD 的百分比差异。
样本数据
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) / old
或new / 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 月有270
。270 - 110 = 160
和160 / 110 = 1.45
。您现有的查询已经 returns 结果。 FWIW,您也可以使用new/old-1
以更简单的方式获得相同的结果。