MySQL получит сумму с левых объединений - PullRequest
0 голосов
/ 04 апреля 2019

У меня три стола.

  1. РЕГИОНЫ
  2. КУХНЯ
  3. БАННЕРЫ

Если я выполню этот запрос

SELECT SUM(fee) FROM BANNERS;

Вывод будет 10000

Если я выполню этот запрос

SELECT SUM(fee) FROM CUISINE;

Выход будет 12,800

Но если я выполню этот запрос

SELECT REGIONS.name,
sum(BANNERS.fee) as banner_revenue,
sum(CUISINE.fee) as cuisine_revenue
FROM REGIONS
LEFT JOIN BANNERS ON REGIONS.id = BANNERS.region_id
LEFT JOIN CUISINE ON REGIONS.id = CUISINE.region_id
GROUP BY REGIONS.name;

Вывод неправильный. Мой желаемый вывод

name    | banner_revenue | cuisine_revenue
------------------------------------------
NY      | 10,000         | 4,800
Paris   | NULL           | 8,000
London  | NULL           | NULL

Воспроизведение скрипты БД

Почему это могло случиться? Пожалуйста, обратитесь к моей скрипке БД.

Ответы [ 2 ]

1 голос
/ 04 апреля 2019

Если вы запустите

SELECT *
       FROM REGIONS
            LEFT JOIN BANNERS
                      ON REGIONS.id = BANNERS.region_id
            LEFT JOIN CUISINE
                      ON REGIONS.id = CUISINE.region_id;

вы заметите, что для каждой пары баннеров региона все кухни объединяются, таким образом «умножая» кухни. То есть их сборы также умножаются.

Выполните группировку в производных таблицах и объедините их, чтобы получить желаемый результат.

SELECT r.name,
       sb.fee,
       sc.fee
       FROM REGIONS r
            LEFT JOIN (SELECT sum(b.fee) fee,
                              b.region_id
                              FROM BANNERS b
                              GROUP BY b.region_id) sb
                      ON sb.region_id = r.id
            LEFT JOIN (SELECT sum(c.fee) fee,
                              c.region_id
                              FROM CUISINE c
                              GROUP BY c.region_id) sc
                      ON sc.region_id = r.id;
0 голосов
/ 04 апреля 2019

Рассмотрим следующее:

SELECT r.name
     , x.header
     , x.fee 
  FROM REGIONS r
  LEFT 
  JOIN 
     ( SELECT 'banner' header, region_id, fee FROM banners
       UNION
       SELECT 'cuisine', region_id, fee FROM cuisine
     ) x
    ON x.region_id = r.id 
 ORDER  
    BY r.name;


    +--------+---------+------+
    | name   | header  | fee  |
    +--------+---------+------+
    | London | NULL    | NULL |
    | NY     | cuisine | 2500 |
    | NY     | cuisine | 2300 |
    | NY     | banner  | 2000 |
    | NY     | banner  | 5000 |
    | NY     | banner  | 3000 |
    | Paris  | cuisine | 8000 |
    +--------+---------+------+
...