Подтвердить что ты не робот

MySQL присоединяется к группе таблиц по сумме

У меня проблема с объединением таблиц, вот примеры таблиц:

Таблица A: (30 строк)

╔════╦════════════╦═════════════╗
║ ID ║ Name       ║ Description ║
╠════╬════════════╬═════════════╣
║ 1  ║ Type       ║ Unicode Art ║
║ 2  ║ Header     ║ Spreadsheet ║
║ 3  ║ Auto Align ║ Off         ║
╚════╩════════════╩═════════════╝

Таблица B: (100 строк)

╔════╦════════════╦═════════════╦═════════╗
║ ID ║ Name       ║ Description ║ TableA  ║
╠════╬════════════╬═════════════╬═════════╣
║ 1  ║ Type       ║ Unicode Art ║ 1       ║
║ 2  ║ Header     ║ Spreadsheet ║ 1       ║
║ 3  ║ Auto Align ║ Off         ║ 2       ║
╚════╩════════════╩═════════════╩═════════╝

Таблица C: (8000 строк)

╔════╦════════════╦═════════════╦═════════╗
║ ID ║ Article    ║ Text        ║ TableB  ║
╠════╬════════════╬═════════════╬═════════╣
║ 1  ║ Type       ║ Unicode Art ║ 1       ║
║ 2  ║ Header     ║ Spreadsheet ║ 1       ║
║ 3  ║ Auto Align ║ Off         ║ 2       ║
╚════╩════════════╩═════════════╩═════════╝

Таблица D: (100 000 строк и подсчет)

╔════╦═══════════╦════════════╦═════════════╦═════════╗
║ ID ║ Date      ║ Clicks     ║ Impressions ║ TableC  ║
╠════╬═══════════╬════════════╬═════════════╬═════════╣
║ 1  ║ 20120814  ║ 10         ║ 3           ║ 1       ║
║ 2  ║ 20120815  ║ 13         ║ 5           ║ 1       ║
║ 3  ║ 20120816  ║ 15         ║ 10          ║ 2       ║
╚════╩═══════════╩════════════╩═════════════╩═════════╝

Таблица E: (200 000 строк и подсчет)

╔════╦═══════════╦════════════╦═══════════╦═════════╗
║ ID ║ Date      ║ Views      ║ Visitors  ║ TableC  ║
╠════╬═══════════╬════════════╬═══════════╬═════════╣
║ 1  ║ 20120814  ║ 10         ║ 3         ║ 1       ║
║ 2  ║ 20120815  ║ 13         ║ 5         ║ 1       ║
║ 3  ║ 20120816  ║ 15         ║ 10        ║ 2       ║
║ 4  ║ 20120817  ║ 8          ║ 7         ║ 2       ║
║ 5  ║ 20120818  ║ 9          ║ 4         ║ 2       ║
╚════╩═══════════╩════════════╩═══════════╩═════════╝

Я запрашиваю эти таблицы с помощью одного оператора sql:

SELECT
       A.name,
       A.Description,
       SUM(D.clicks),
       SUM(D.Impressions),
       SUM(E.Views),
       SUM(E.Visitors)
FROM 
       A 
       LEFT JOIN B
         ON A.ID=B.TableA
       LEFT JOIN C
         ON B.ID=C.TableB
       LEFT JOIN D
         ON C.ID=D.TableC
       LEFT JOIN E
         ON C.ID=E.TableC
GROUP BY
       A.ID

Проблема заключается в том, что запрос возвращает недопустимый SUM для таблицы D и таблицы E
Однако, если в таблице запроса D и в таблице E в invidual queries я получаю правильные значения:

SELECT
       A.name,
       A.Description,
       SUM(D.clicks),
       SUM(D.Impressions)
FROM 
       A 
       LEFT JOIN B
         ON A.ID=B.TableA
       LEFT JOIN C
         ON B.ID=C.TableB
       LEFT JOIN D
         ON C.ID=D.TableC
GROUP BY
       A.ID

ИЗМЕНИТЬ 1:
Я пробовал ПРАВОЕ ПРИСОЕДИНЕНИЕ, ПРИСОЕДИНЯЮТСЯ, ЛЕВАЯ ВЗАИМОДЕЙСТВУЮЩАЯ ПРИСОЕДИНИТЬ, ни одна из них не работала,
Возможно, я использовал их в неправильных местах.
Но в первом заявлении, где я получил "все включено", значения умножаются
в тысячу раз выше, чем они есть на самом деле.

4b9b3361

Ответ 1

Вам нужно сгладить таблицу D и E. Тогда я полагаю, что A и B являются просто поисками для C, поэтому нет необходимости делать GROUP BY на A: http://www.sqlfiddle.com/#!2/fccf1/8

Я удалил шум (A и B), поскольку я не могу видеть (пока), как A и B связаны с суммированием информации для C

Попробуйте следующее:

SELECT
       C.Article,
       C.Text,

       COALESCE(D.ClicksSum,0) AS ClicksSum,
       COALESCE(D.ImpressionsSum,0) AS ImpressionsSum,

       COALESCE(E.ViewsSum,0) AS ViewsSum,
       COALESCE(E.VisitorsSum,0) AS VisitorsSum
FROM 
       C

       LEFT JOIN 
       (
         SELECT TableC, SUM(Clicks) AS ClicksSum, SUM(Impressions) AS ImpressionsSum
         FROM D
         GROUP BY TableC
       ) D ON C.ID=D.TableC

       LEFT JOIN 
       (
         SELECT TableC, SUM(Views) AS ViewsSum, SUM(Visitors) AS VisitorsSum
         FROM E
         GROUP BY TableC       
       ) E ON C.ID=E.TableC

Вывод:

|    ARTICLE |        TEXT | CLICKSSUM | IMPRESSIONSSUM | VIEWSSUM | VISITORSSUM |
----------------------------------------------------------------------------------
|       Type | Unicode Art |        23 |              8 |       23 |           8 |
|     Header | Spreadsheet |        15 |             10 |       32 |          21 |
| Auto Align |         Off |         0 |              0 |        0 |           0 |

Заметьте, что я не печатал эту схему в моей записи sqlfiddle вручную, я использую sqlfiddle Text to DDL

Мне нравится http://sqlfiddle.com, его Текст в DDL может даже анализировать данные из вашего искусства ASCII ツ


Увидев вашу более ясную цель (из вашего комментария), это может быть так: http://www.sqlfiddle.com/#!2/fccf1/13

SELECT
       A.Name, A.Description,

       COALESCE(SUM(D.ClicksSum),0) AS ClicksSum,
       COALESCE(SUM(D.ImpressionsSum),0) AS ImpressionsSum,

       COALESCE(SUM(E.ViewsSum),0) AS ViewsSum,
       COALESCE(SUM(E.VisitorsSum),0) AS VisitorsSum
FROM 
       C

       LEFT JOIN 
       (
         SELECT TableC, SUM(Clicks) AS ClicksSum, SUM(Impressions) AS ImpressionsSum
         FROM D
         GROUP BY TableC
       ) D ON C.ID=D.TableC

       LEFT JOIN 
       (
         SELECT TableC, SUM(Views) AS ViewsSum, SUM(Visitors) AS VisitorsSum
         FROM E
         GROUP BY TableC       
       ) E ON C.ID=E.TableC

       RIGHT JOIN B ON B.ID = C.TableB
       RIGHT JOIN A ON A.ID = B.TableA

GROUP BY A.ID

Вывод:

|       NAME | DESCRIPTION | CLICKSSUM | IMPRESSIONSSUM | VIEWSSUM | VISITORSSUM |
----------------------------------------------------------------------------------
|       Type | Unicode Art |        38 |             18 |       55 |          29 |
|     Header | Spreadsheet |         0 |              0 |        0 |           0 |
| Auto Align |         Off |         0 |              0 |        0 |           0 |

Приведенный выше подход может по-прежнему производить декартовы продукты, сгладить SubCategory (B), прежде чем группировать его в категорию (A): http://www.sqlfiddle.com/#!2/fccf1/19

SELECT 
  A.Name, A.Description,
  COALESCE(SUM(B.ClicksSum),0) AS ClicksSum,
  COALESCE(SUM(B.ImpressionsSum),0) AS ImpressionsSum,
  COALESCE(SUM(B.ViewsSum),0) AS ViewsSum,
  COALESCE(SUM(B.VisitorsSum),0) AS VisitorsSum
FROM A
LEFT JOIN
(

  SELECT 
    B.ID, B.TableA,
    SUM(C.ClicksSum) AS ClicksSum,
    SUM(C.ImpressionsSum) AS ImpressionsSum,
    SUM(C.ViewsSum) AS ViewsSum,
    SUM(C.VisitorsSum) AS VisitorsSum
  FROM B
  LEFT JOIN
  (

    SELECT
      C.TableB,

      D.ClicksSum,
      D.ImpressionsSum,

      E.ViewsSum,
      E.VisitorsSum
    FROM 
    C

    LEFT JOIN 
    (
      SELECT TableC, SUM(Clicks) AS ClicksSum, SUM(Impressions) AS ImpressionsSum
      FROM D
      GROUP BY TableC
    ) D ON C.ID=D.TableC

    LEFT JOIN 
    (
      SELECT TableC, SUM(Views) AS ViewsSum, SUM(Visitors) AS VisitorsSum
      FROM E
      GROUP BY TableC       
    ) E ON C.ID=E.TableC

  ) C ON C.TableB = B.ID
  GROUP BY B.ID

) B ON B.TableA = A.ID
GROUP BY A.ID

Вывод:

|       NAME | DESCRIPTION | CLICKSSUM | IMPRESSIONSSUM | VIEWSSUM | VISITORSSUM |
----------------------------------------------------------------------------------
|       Type | Unicode Art |        38 |             18 |       55 |          29 |
|     Header | Spreadsheet |         0 |              0 |        0 |           0 |
| Auto Align |         Off |         0 |              0 |        0 |           0 |

Ответ 2

Обе таблицы D и таблица E связаны с остальными таблицей C. Таким образом, ваш первый запрос дает декартовое произведение всех строк таблицы D раз всех строк таблицы E, а функция SUM объединяет этот декартово произведение. Вероятно, вам также придется группировать таблицу C, а не только таблицу A.