ЛЕВЫЕ СОЕДИНЕНИЯ двух таблиц, СУММА, ГРУППА - PullRequest
0 голосов
/ 20 января 2019

У меня есть две таблицы, INPUT и OUTPUT.

Таблица INPUT с идентификатором столбцов, productName, QTY, buyPrice, sellPrice. Таблица ВЫХОДА с идентификатором столбцов, productName, QTY. Оба могут иметь несколько входов с одинаковым productName и разным (или одинаковым) QTY. Выходной файл не может иметь productName, который не отображается в таблице INPUT первым.

Я пытаюсь запросить обе таблицы и получить конечный результат - что-то вроде этого: productName, SUM (QTY) из таблицы INPUT (GROUP BY productName), productName, SUM (QTY) из OUTPUT (GROUP BY productName)

Пример:

ВХОД

ID | productName | QTY | buyPrice | sellPrice
1  |  dress 007  |  2  |   700    |   1400
2  |  shirt 001  |  4  |   800    |   1900
3  |  dress 007  | 10  |   700    |   1500
4  |  dress 007  |  6  |   900    |   2900
5  |  shirt 001  |  2  |   750    |   1600
6  |    hat 008  |  2  |   300    |    600

OUTPUT

ID | productName | QTY
1  |  dress 007  |  4
2  |  shirt 001  |  2
3  |  dress 007  |  1
4  |  dress 007  |  1
5  |  shirt 001  |  3

РЕЗУЛЬТАТ ДОЛЖЕН БЫТЬ

productName | SUM(QTY)INPUT | productName | SUM(QTY)OUTPUT
 dress 007  |      18       |  dress 007  |        6
 shirt 001  |       6       |  shirt 001  |        5
   hat 008  |       2       |     null    |       null

Легко сделать SUM и GROUP, когда это только одна таблица, но когда я пытаюсь ВЛЕВО СОЕДИНИТЬ обе таблицы и GROUP по productName, я получаю неправильные значения для SUM. Где я ошибаюсь?

Легкая часть:

SELECT a.productName , SUM(a.QTY), a.buyPrice , a.sellPrice
FROM input a
GROUP BY a.productName

Ошибка:

SELECT a.productName , SUM(a.QTY), b.productName , SUM(b.QTY)
FROM input a LEFT JOIN output b
ON a.productName = b.productName 
GROUP BY a.productName

Ответы [ 4 ]

0 голосов
/ 20 января 2019

Добро пожаловать в SO

Существует способ без подзапроса для достижения этой цели. Это математически:)

Поскольку вы работаете с двумя таблицами, вы получите результат, умноженный на идентификаторы, на продукт. Так что просто разделите сумму на количество названий продуктов, разделенных на уникальные идентификаторы, соответствующие этим продуктам:)

Так что-то вроде этого поможет: Схема (MySQL v5.7)

CREATE TABLE INPUT (
  `ID` INTEGER,
  `productName` VARCHAR(9),
  `QTY` INTEGER,
  `buyPrice` INTEGER,
  `sellPrice` INTEGER
);

INSERT INTO INPUT
  (`ID`, `productName`, `QTY`, `buyPrice`, `sellPrice`)
VALUES
  ('1', 'dress 007', '2', '700', '1400'),
  ('2', 'shirt 001', '4', '800', '1900'),
  ('3', 'dress 007', '10', '700', '1500'),
  ('4', 'dress 007', '6', '900', '2900'),
  ('5', 'shirt 001', '2', '750', '1600'),
  ('6', 'hat 008', '2', '300', '600');

CREATE TABLE OUTPUT (
  `ID` INTEGER,
  `productName` VARCHAR(9),
  `QTY` INTEGER
);

INSERT INTO OUTPUT
  (`ID`, `productName`, `QTY`)
VALUES
  ('1', 'dress 007', '4'),
  ('2', 'shirt 001', '2'),
  ('3', 'dress 007', '1'),
  ('4', 'dress 007', '1'),
  ('5', 'shirt 001', '3');

Запрос № 1

SELECT I.productName, 
       SUM(I.QTY)/(COUNT(I.productName)/count(distinct I.ID)) 
                                          as "SUM(QTY)INPUT",
       O.productName,                      
       SUM(O.QTY)/(COUNT(O.productName)/count(distinct O.ID))  
                                          as "SUM(QTY)OUTPUT"
FROM INPUT I
LEFT OUTER JOIN OUTPUT O ON I.productName = O.productName
GROUP BY I.productName
ORDER BY 2 DESC;

| productName | SUM(QTY)INPUT | SUM(QTY)OUTPUT | productName |
| ----------- | ------------- | -------------- | ----------- |
| dress 007   | 18            | 6              | dress 007   |
| shirt 001   | 6             | 5              | shirt 001   |
| hat 008     | 2             | null           | null        |

https://www.db -fiddle.com / ж / Dp7yaNkVf3JW2DZrrvL7G / 1 * 1 021 *

0 голосов
/ 20 января 2019

Вы можете использовать union all:

SELECT  IF(sum(input) , productName, null) productName, sum(input) input,
        IF(sum(output), productName, null) productName, sum(output) output
FROM    (
            SELECT productName, QTY input, null output
            FROM input
            UNION ALL
            SELECT productName, null, QTY
            FROM output
        ) as sub
GROUP BY productName

sqlfiddle

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

0 голосов
/ 20 января 2019

Я думаю, union all - это путь. Я бы сделал:

select productName, sum(input) as input_qty, sum(output) as output_qty
from ((select productName, qty as input, null as output
       from input
      ) union all
      (select productName, null, qty
       from output
      )
     ) io
group by productName;

Обратите внимание, что productName появляется только один раз в наборе результатов. Я не вижу смысла включать его дважды. Если нет строки output (или input), то соответствующая qty будет NULL.

0 голосов
/ 20 января 2019

Я бы сделал агрегацию в подзапросах и присоединился бы к ним.

SELECT input.productname,
       input.quantity input_quantity,
       output.quantity output_quantity
       FROM (SELECT productname,
                    sum(qty) quantity
                    FROM input
                    GROUP BY productname) input
            LEFT JOIN (SELECT productname,
                              sum(qty) quantity
                              FROM output
                              GROUP BY productname) output
                      ON output.productname = input.productname;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...