Skip to content
Advertisement

Calculate share of value per day per country

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');

Expected Result:

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)

I want to calculate the sales share per country per day as it is done in the question here.

However, since I added the column channel in the database I am not getting the right shares anymore using this query:

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;

How do I need to modify this query to get the expected results?

Advertisement

Answer

here is one way:

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;

or

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;
User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement