【问题标题】:Ponderate average MYSQLPonderate 平均 MYSQL
【发布时间】:2018-07-14 15:26:12
【问题描述】:

我们有一个旅游运营商数据库 (MYSQL) 的小模拟器,我们被要求获取一个查询,该查询为我们提供了我们所拥有的旅游持续时间的加权平均值。

https://en.wikipedia.org/wiki/Weighted_arithmetic_mean

使用子查询,我得到了每次旅行持续的天数以及每次旅行的总重量,但我被卡住了,不知道如何从这里获得加权平均值。我知道我必须从我已经得到的结果中使用另一个选择,但我希望能得到一些帮助。

这里的SQLfiddle:

http://sqlfiddle.com/#!9/53d80/2

表格和数据

CREATE TABLE STAGE
(
    ID INT AUTO_INCREMENT NOT NULL,
    TOUR INT NOT NULL,
    TYPE INT NOT NULL,
    CITY INT NOT NULL,
    DAYS INT NOT NULL,
    PRIMARY KEY (ID)
);

CREATE TABLE TOUR
(
    ID INT AUTO_INCREMENT NOT NULL,
    DESCRIPTION VARCHAR(255) CHARACTER SET UTF8 COLLATE UTF8_UNICODE_CI 
    NOT NULL,
    STARTED_ON DATE NOT NULL,
    TYPE INT NOT NULL,
    PRIMARY KEY (ID)
);

INSERT INTO TOUR (DESCRIPTION, STARTED_ON, TYPE) VALUES 
('Mediterranian Cruise','2018-01-01',3),
('Trip to Nepal','2017-12-01',1),
('Tour in Nova York','2015-04-24',5),
('A week at the Amazones','2014-09-11',2),
('Visiting the Machu Picchu','2013-02-19',4);

INSERT INTO STAGE (TOUR, TYPE, CITY, DAYS) VALUES 
(1, 1, 38254, 1),
(1, 2, 22460, 3),
(1, 2, 47940, 3),
(1, 2, 42600, 4),
(1, 3, 38254, 1),
(2, 1, 13097, 1),
(2, 2, 29785, 5),
(2, 3, 13097, 1),
(3, 1, 788, 2); ,
(3, 2, 48019, 6),
(3, 3, 788, 1),
(4, 1, 38254, 2),
(4, 2, 8703, 3);,
(4, 3, 38254, 4),
(5, 1, 10453, 1),
(5, 2, 32045, 5),
(5, 3, 10453, 2);

查询:

SELECT
    AVG(TD.TOUR_DAYS) AS AVERAGE_DAYS,
    COUNT(TD.TOUR_ID) AS WEIGHT
FROM
(
    SELECT
        TOUR.ID AS TOUR_ID, 
        SUM(DAYS) AS TOUR_DAYS,
        COUNT(STAGE.ID) AS STAGE_DAYS
    FROM
        TOUR
    INNER JOIN
        STAGE
    ON
        TOUR.ID = STAGE.TOUR
    GROUP BY
        TOUR.ID
) AS TD
GROUP BY 
    TD.TOUR_DAYS

加权平均值为:
(1×7+1×8+2×9+1×12) / (1+1+2+1) = 9

【问题讨论】:

  • 很高兴你创造了一个小提琴。但是您还应该在问题中发布示例数据和查询。同时发布您的预期结果。
  • 那么预期的结果是什么? 9?
  • 是的,应该是 9
  • 在这种情况下“思考”是什么意思?

标签: mysql dml


【解决方案1】:

加权 AVG 可以用SUM(value * wheight) / SUM(wheight) 计算。在你的情况下:

SELECT SUM(AVERAGE_DAYS * WEIGHT) / SUM(WEIGHT)
FROM (
    SELECT
            AVG(TD.TOUR_DAYS) AS AVERAGE_DAYS,
            COUNT(TD.TOUR_ID) AS WEIGHT
        FROM
        (
            SELECT
                TOUR.ID AS TOUR_ID, 
                SUM(DAYS) AS TOUR_DAYS,
                COUNT(STAGE.ID) AS STAGE_DAYS
            FROM
                TOUR
            INNER JOIN
                STAGE
            ON
                TOUR.ID = STAGE.TOUR
            GROUP BY
                TOUR.ID
        ) AS TD
        GROUP BY 
            TD.TOUR_DAYS
) sub

http://sqlfiddle.com/#!9/53d80/4

我不是 100% 确定,但看起来下面的查询是完全一样的:

SELECT AVG(TOUR_DAYS)
FROM (
  SELECT TOUR, SUM(DAYS) AS TOUR_DAYS
  FROM STAGE
  GROUP BY TOUR
) sub;

甚至没有任何子查询:

SELECT SUM(DAYS) / COUNT(DISTINCT TOUR)
FROM STAGE;

这意味着,该要求应简化为“获取每次旅行的平均天数”。

【讨论】:

  • 哇,好吧没想到这样做,我不知道我可以在函数 sum() 中操作。谢谢!
  • @PolVilarrasa 检查更新。似乎要求过于复杂。
  • 你得到的结果肯定是一样的,但目标是使用加权平均公式得到结果。我们已经收到了您发布的最后两个查询,但任务是使用加权平均公式通过子查询获取它。
  • 那么你至少应该简化你的子查询:sqlfiddle.com/#!9/53d80/27
猜你喜欢
  • 1970-01-01
  • 2015-02-19
  • 2012-12-29
  • 1970-01-01
  • 2017-01-13
  • 2011-06-29
  • 2011-01-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多