考虑平均MYSQL

时间:2018-02-04 17:57:44

标签: mysql dml

我们有一个旅游运营商DB(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

weigthed avg将是:
 (1×7 + 1×8 + 2×9 + 1×12)/(1 + 1 + 2 + 1)= 9

1 个答案:

答案 0 :(得分:1)

可以使用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

我不是百分百肯定,但看起来以下查询完全相同:

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;

这意味着,要求应该简化为“#34;获得每次旅行的平均天数"。