重度平均值 MYSQL

Ponderate average MYSQL

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

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

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

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

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

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;

这意味着,要求应简化为 "Get average number of days per tour"。