簡體   English   中英

如何根據SQL中的上個月平均值和去年同月平均值計算值

[英]How to calculate value based on average of previous month and average of same month last year in SQL

我想根據上個月和去年同月的實際情況計算打開率和點擊率的目標。 我的表格按日匯總,並按月和年分組以獲得月平均值。 然后,我創建了一個自我加入,以將我當前的日期加入到前幾個月的結果中。 除了 1 月之外,這在所有月份都可以正常工作,因為 SQL 不知道它應該在 12 日加入 1。有沒有辦法在我的 join 子句中指定這一點?

本質上,2021 年 1 月的結果不應該是 null,因為我有 2020 年 12 月的數據。

這是我的數據和我的查詢:

CREATE TABLE exasol_last_year_avg(
    date_col date,
    country text,
    brand text,
    category text,
    delivered integer,
    opened integer,
    clicked integer
)

INSERT INTO exasol_last_year_avg 
(date_col,country,brand,category,delivered,opened,clicked) VALUES
(2021-01-01,'AT','brand1','cat1',100,60,23),
(2021-01-01,'AT','brand1','cat2',200,50,45),
(2021-01-01,'AT','brand2','cat1',300,49,35),
(2021-01-01,'AT','brand2','cat2',400,79,57),
(2021-02-02,'AT','brand1','cat1',130,78,30),
(2021-02-02,'AT','brand1','cat2',260,65,59),
(2021-02-02,'AT','brand2','cat1',390,64,46),
(2021-02-02,'AT','brand2','cat2',520,103,74),
(2020-12-02,'AT','brand1','cat1',130,78,30),
(2020-12-02,'AT','brand1','cat2',260,65,59),
(2020-12-02,'AT','brand2','cat1',390,64,46),
(2020-12-02,'AT','brand2','cat2',520,103,74),
(2020-02-02,'AT','brand1','cat2',236,59,53),
(2020-02-02,'AT','brand2','cat1',355,58,41),
(2020-02-02,'AT','brand2','cat2',473,93,67),
(2020-02-02,'AT','brand1','cat1',118,71,27)

這是用 PostgresSQL 編寫的,因為我認為它對大多數人來說更容易訪問,但我的生產數據庫是 Exasol!

select *
from
(Select month_col,
           year_col,
           t_campaign_cmcategory,
           t_country,
           t_brand,
           (t2_clicktoopenrate + t3_clicktoopenrate)/2 as target_clicktoopenrate,
           (t2_openrate + t3_openrate)/2 as target_openrate
    from (
with CTE as (
select extract(month from date_col) as month_col,
       extract(year from date_col) as year_col, 
        category as t_campaign_cmcategory,
        country as t_country,
        brand as t_brand,
        round(sum(opened)/nullif(sum(delivered),0),3) as OpenRate,
        round(sum(clicked)/nullif(sum(opened),0),3) as ClickToOpenRate
from public.exasol_last_year_avg
group by 1, 2, 3, 4, 5)
select t1.month_col,
           t1.year_col,
           t2.month_col as t2_month_col,
           t2.year_col as t2_year_col,
           t3.month_col as t3_month_col,
           t3.year_col as t3_year_col,
           t1.t_campaign_cmcategory,
           t1.t_country,
           t1.t_brand,
           t1.OpenRate,
           t1.ClickToOpenRate,
           t2.OpenRate as t2_OpenRate,
           t2.ClickToOpenRate as t2_ClickToOpenRate,
           t3.OpenRate as t3_OpenRate,
           t3.ClickToOpenRate as t3_ClickToOpenRate
    from CTE t1
    left join CTE t2
    on t1.month_col = t2.month_col + 1
    and t1.year_col = t2.year_col
    and t1.t_campaign_cmcategory = t2.t_campaign_cmcategory
    and t1.t_country = t2.t_country
    and t1.t_brand = t2.t_brand
    left join CTE t3
    on t1.month_col = t3.month_col
    and t1.year_col = t3.year_col + 1
    and t1.t_campaign_cmcategory = t3.t_campaign_cmcategory
    and t1.t_country = t3.t_country
    and t1.t_brand = t3.t_brand) as target_base) as final_tbl

從聚合查詢開始:

select date_trunc('month', date_col), country, brand, 
       sum(opened) * 1.0 / nullif(sum(delivered), 0) as OpenRate,
       sum(clicked) * 1.0 / nullif(sum(opened), 0) as ClickToOpenRate
from exasol_last_year_avg
group by 1, 2, 3;

然后,使用 window 函數。 假設您每個月都有一個值(沒有間隙)。 你可以只使用lag() 我不確定你的最終計算是什么,但這會帶來數據:

with mcb as (
      select date_trunc('month', date_col) as yyyymm, country, brand, 
             sum(opened) * 1.0 / nullif(sum(delivered), 0) as OpenRate,
             sum(clicked) * 1.0 / nullif(sum(opened), 0) as ClickToOpenRate
      from exasol_last_year_avg
      group by 1, 2, 3
     )
select mcb.*,
       lag(openrate, 1) over (partition by country, brand order by yyyymm) as prev_month_openrate,
       lag(ClickToOpenRate, 1) over (partition by country, brand order by yyyymm) as prev_month_ClickToOpenRate,
       lag(openrate, 12) over (partition by country, brand order by yyyymm) as prev_year_openrate,
       lag(ClickToOpenRate, 12) over (partition by country, brand order by yyyymm) as prev_year_ClickToOpenRate
from mcb;

這適用於不同的連接條件:

select *
from
(Select month_col,
           year_col,
           t_campaign_cmcategory,
           t_country,
           t_brand,
           (t2_clicktoopenrate + t3_clicktoopenrate)/2 as target_clicktoopenrate,
           (t2_openrate + t3_openrate)/2 as target_openrate
    from (
with CTE as (
select extract(month from date_col) as month_col,
       extract(year from date_col) as year_col, 
        category as t_campaign_cmcategory,
        country as t_country,
        brand as t_brand,
        round(sum(opened)/nullif(sum(delivered),0),3) as OpenRate,
        round(sum(clicked)/nullif(sum(opened),0),3) as ClickToOpenRate
from public.exasol_last_year_avg
group by 1, 2, 3, 4, 5)
select t1.month_col,
           t1.year_col,
           t2.month_col as t2_month_col,
           t2.year_col as t2_year_col,
           t3.month_col as t3_month_col,
           t3.year_col as t3_year_col,
           t1.t_campaign_cmcategory,
           t1.t_country,
           t1.t_brand,
           t1.OpenRate,
           t1.ClickToOpenRate,
           t2.OpenRate as t2_OpenRate,
           t2.ClickToOpenRate as t2_ClickToOpenRate,
           t3.OpenRate as t3_OpenRate,
           t3.ClickToOpenRate as t3_ClickToOpenRate
    from CTE t1
    left join CTE t2
-- adjusted join condition
    on ((t1.month_col = (CASE WHEN t1.month_col = 1 then t2.month_col - 11 END) and t1.year_col = t2.year_col + 1)
or (t1.month_col = (CASE WHEN t1.month_col != 1 then t2.month_col + 1 END) and t1.year_col = t2.year_col))
    and t1.t_campaign_cmcategory = t2.t_campaign_cmcategory
    and t1.t_country = t2.t_country
    and t1.t_brand = t2.t_brand
    left join CTE t3
    on t1.month_col = t3.month_col
    and t1.year_col = t3.year_col + 1
    and t1.t_campaign_cmcategory = t3.t_campaign_cmcategory
    and t1.t_country = t3.t_country
    and t1.t_brand = t3.t_brand) as target_base) as final_tbl

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM