计算每个国家每天的价值份额

时间:2021-03-15 15:27:35

标签: sql postgresql

DB-Fiddle

CREATE TABLE sales (
    id SERIAL PRIMARY KEY,
    event_date DATE,
    country VARCHAR,
    channel VARCHAR,
    sales DECIMAL
);

INSERT INTO sales
(event_date, country, channel, sales)
VALUES 
('2020-02-08', 'DE', 'channel_01', '500'),
('2020-02-08', 'DE', 'channel_02', '400'),
('2020-02-08', 'DE', 'channel_03', '200'),
('2020-02-08', 'FR', 'channel_01', '900'),
('2020-02-08', 'FR', 'channel_02', '800'),
('2020-02-08', 'NL', 'channel_01', '100'),

('2020-04-15', 'DE', 'channel_01', '700'),
('2020-04-15', 'FR', 'channel_01', '500'),
('2020-04-15', 'NL', 'channel_01', '850'),
('2020-04-15', 'NL', 'channel_02', '250'),
('2020-04-15', 'NL', 'channel_03', '300');

预期结果:

event_date  |   country   |     share_per_day_per_country
------------|-------------|----------------------------------------------
2020-02-08  |      DE     |       0.379 (=1100/2900)
2020-02-08  |      FR     |       0.586 (=1700/2900)
2020-02-08  |      NL     |       0.034 (=100/2900)
------------|-------------|----------------------------------------------
2020-04-15  |      DE     |       0.269 (=700/2600)
2020-04-15  |      FR     |       0.192 (=500/2600)
2020-04-15  |      NL     |       0.538 (=1400/2600)

我想计算每个国家/地区每天的销售份额,正如在问题 here 中所做的那样。

但是,由于我在数据库中添加了 channel 列,因此我无法再使用此查询获得正确的份额:

SELECT
s.event_date,
s.country,
s.sales,

s.sales/SUM(s.sales) OVER (PARTITION BY s.event_date) AS share_per_day_per_country

FROM sales s
GROUP BY 1,2,3
ORDER BY 1,2;

我需要如何修改这个查询才能获得预期的结果?

1 个答案:

答案 0 :(得分:0)

这是一种方法:

select distinct
    s.event_date,
    s.country,
    SUM(s.sales) OVER (PARTITION BY s.event_date, s.country) / SUM(s.sales) OVER (PARTITION BY s.event_date) AS share_per_day
from
    sales s
ORDER BY
    s.event_date,
    s.country;

SELECT
    s.event_date,
    s.country,
    sum(sales) / max(share_per_day) share_per_day_per_country
from
    (
        select *,SUM(s.sales) OVER (PARTITION BY s.event_date) AS share_per_day
        from sales s
    ) s
GROUP BY
    s.event_date,s.country
ORDER BY
    s.event_date,s.country;