Search code examples
mysqlsqlcasewindow-functions

Check if sales-status in one country per campaign has changed and assign it to all countries per campaign in the results


DB-Fiddle:

CREATE TABLE operations (
    id int auto_increment primary key,
    campaign VARCHAR(255),
    country VARCHAR(255),
    sales_status VARCHAR(255),
    quantity INT
);

INSERT INTO operations
(campaign, country, sales_status, quantity
)
VALUES 
("C001", "DE", "demand", "100"),
("C001", "US", "shipped", "300"),
("C001", "NL", "shipped", "700"),
("C001", "FR", "shipped", "400"),

("C002", "DE", "demand", "500"),
("C002", "US", "demand", "900"),
("C002", "FR", "shipped", "200"),

("C003", "US", "demand", "600"),
("C003", "NL", "demand", "250"),
("C003", "FR", "demand", "150"),
("C003", "PL", "demand", "550"),

("C004", "DE", "shipped", "825"),
("C004", "PL", "shipped", "462");

Expected Result:

campaign |  country  |   sales_status  |     quantity
---------|-----------|-----------------|------------------       
C001     |     DE    |     shipped     |       100
C001     |     FR    |     shipped     |       400
C001     |     NL    |     shipped     |       700
C001     |     US    |     shipped     |       300
         |           |
C002     |     DE    |     shipped     |       500
C002     |     FR    |     shipped     |       200
C002     |     US    |     shipped     |       900
         |           |                 |
C003     |     FR    |     demand      |       150
C003     |     NL    |     demand      |       250
C003     |     PL    |     demand      |       550
         |           |                 |
C004     |     DE    |     shipped     |       250
C004     |     PL    |     shipped     |       550

In the table above you can see different campaigns and their sales_staus per country.
Now, in the result I want to achieve that if one country per campaign is in sales_status shipped every other country should also be switched to sales_status shipped.

For example in C002 the country FR is in sales_status shipped.
Therefore, all the other countries are changed from demand to shipped in the results.

I tried this query but could not make it work:

SELECT
campaign,
country,
(CASE WHEN MIN(sales_status) OVER (PARTITION BY country) = MAX(sales_status) OVER (PARTITION BY country)
THEN MIN(sales_status) ELSE MAX(sales_status) END) AS sales_status,
quantity
FROM operations
GROUP BY 1,2;

What do I need to change to get the expected result?


Solution

  • if one country per campaign is in sales_status shipped every other country should also be switched to sales_status shipped.

    You can use window functions and a case expression:

    select
        campaign,
        country,
        case when max(sales_status = 'shipped') over(partition by campaign) = 1
            then 'shipped'
            else sales_status
        end as sales_status,
        quantity
    from operations