【问题标题】:Assign a certain value to all other values if at least one criteria per value is met如果每个值至少满足一个条件,则将某个值分配给所有其他值
【发布时间】:2020-09-23 06:14:54
【问题描述】:

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

预期结果:

campaign    sales_status    SUM(quantity)
C001          shipped             1500
C002          shipped             1600
C003          demand              1550
C004          shipped             1287

在上述结果中,我希望每个广告系列的sales_statusshipped,以防每个广告系列至少有一个国家其中sales_statusshipped

例如,在活动C002 中,只有FRshipped,所以结果中的C002 应该在shipped 中。

我试着用这个查询:

SELECT
campaign,
(CASE WHEN MAX(sales_status = 'shipped') OVER (PARTITION BY campaign) = 1
THEN 'shipped' ELSE sales_status END) AS sales_status,
SUM(quantity)
FROM operations
GROUP BY 1;

但是,它没有给我正确的结果。
我需要进行哪些更改才能使其正常工作?

【问题讨论】:

  • 您的代码对于您希望实现的目标而言似乎过于复杂。
  • OVER (PARTITION BY campaign) 没有任何意义 - 您已经通过此列进行了 GROUP BY。所以 MAX() 的聚合版本就足够了。

标签: mysql sql window-functions


【解决方案1】:

为什么不简单

SELECT
campaign,
MAX(sales_status) AS sales_status,
SUM(quantity)
FROM operations
GROUP BY 1;

?

如果可以有另一个 sales_status 值,您可以使用类似

SELECT
campaign,
CASE WHEN SUM(sales_status = 'shipped') 
     THEN 'shipped'
     ELSE 'demand' 
     END AS sales_status,
SUM(quantity)
FROM operations
GROUP BY 1;

fiddle

【讨论】:

    【解决方案2】:

    使用条件聚合:

    SELECT 
      campaign,
      COALESCE(
        MAX(CASE WHEN sales_status = 'shipped' THEN sales_status END), 
        MAX(sales_status)
      ) sales_status,
      SUM(quantity) total
    FROM operations
    GROUP BY campaign;
    

    或者用窗口函数FIRST_VALUE()SUM()

    SELECT DISTINCT 
      campaign,
      FIRST_VALUE(sales_status) OVER (PARTITION BY campaign ORDER BY sales_status = 'shipped' DESC) sales_status,
      SUM(quantity) OVER (PARTITION BY campaign) total
    FROM operations
    

    请参阅demo
    结果:

    > campaign | sales_status | total
    > :------- | :----------- | ----:
    > C001     | shipped      |  1500
    > C002     | shipped      |  1600
    > C003     | demand       |  1550
    > C004     | shipped      |  1287
    

    【讨论】:

      猜你喜欢
      • 2017-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-23
      • 1970-01-01
      • 1970-01-01
      • 2016-02-05
      相关资源
      最近更新 更多