СУММА из 2 разных таблиц на основе группы идентификаторов из третьей таблицы, возвращающая двойное значение, чем ожидаемое значение - PullRequest
1 голос
/ 03 мая 2020

У меня ниже таблицы

1. Единица материала:

id | material_unit
1  | Nos.
2  | lts

2. Таблица материалов:

id | Material_name
1  | bricks
2  | Cement

3. Таблица Грн:

id | material_id | qty | unit
1  | 1           | 100 |   1
2  | 2           | 500 |   1
3  | 2           | 100 |   1
4  | 1           | 200 |   1

4. Таблица потребления:

id | material_id | qty | unit
1  | 1           | 50  |   1
2  | 1           | 50  |   1
3  | 2           | 100 |   1
4  | 2           | 200 |   1

Ожидаемые результаты, как показано ниже:

Material Name | Unit | Total Qty | Total Consumed Qty | Stock
Bricks        | Nos. | 300       | 100                | 200
Cement        | Nos. | 600       | 300                | 300

Таким образом, на вышеуказанных результатах общий кол-во должен быть получен из таблицы Grn, а общее кол-во потребленных из таблицы потребления и Stock является разностью обоих и должен быть Group By Material_id.

Ниже запрос возвращает SUM значений из GRN и таблицы потребления, но он умножает SUM на количество записей в таблице потребления.

Какую ошибку я делаю, может кто-нибудь помочь мне разобраться в моей ошибке.

SELECT sm.material_name as 'Material Name', mu.material_unit as 'Material Unit', sum(g.qty) as 'GRN Qty', sum(c.qty) as 'Consumed Qty', SUM(g.qty) - SUM(c.qty) as 'Stock' from grn g 
JOIN material_table sm ON g.material_id = sm.id
JOIN material_unit_table mu ON g.unit_id = mu.id
JOIN consumption c ON c.material_id = g.material_id

group by g.material_id

Ответы [ 3 ]

0 голосов
/ 03 мая 2020
WITH Grn AS (
    SELECT
        material_id,
        unit,
        SUM(qty) AS 'Total Qty'
    FROM grn
    GROUP BY
        material_id,
        unit
),
Consumption AS (
    SELECT
        material_id,
        SUM(qty) AS 'Consumed Qty'
    FROM consumption
    GROUP BY
        material_id
)
SELECT
    m.Material_name AS 'Material Name',
    u.Material_unit AS Unit,
    g.[Total Qty],
    c.[Consumed Qty],
    g.[Total Qty] - c.[Consumed Qty] AS Stock
FROM Grn g
    INNER JOIN Consumption c ON g.material_id = c.material_id
    INNER JOIN material_unit_table u ON g.unit_id = u.Id
    INNER JOIN material_table m ON g.material_id = m.Id

Этот запрос даст желаемый результат.

Нижняя строка предназначена для удаления material_id дубликатов в таблицах grn и consumption. Таким образом, объединение таблиц consumption и grn на material_id не даст дубликатов.

Примечание : чтобы это работало, в таблице grn нужны все материалы иметь только одну единицу.

0 голосов
/ 03 мая 2020

Потребление удваивает количество строк, поэтому, суммируя количество перед объединением, исправляет числа.

SELECT
MAX(sm.material_name) as 'Material Name'
,  MAX(mu.material_unit) as 'Material Unit'
, sum(g.qty) as 'GRN Qty'
, sum(c.qty) as 'Consumed Qty'
, SUM(g.qty) - SUM(c.qty) as 'Stock' 
from  grn g 
inner JOIN material_table sm ON g.material_id = sm.id
inner JOIN material_unit_table mu ON g.unit = mu.id
INNER JOIN (SELECT `material_id`, SUM(`qty`) qty, `unit` FROM consumption GROUP BY  `material_id`,`unit`) c ON c.material_id = g.material_id
GROUP BY g.material_id

пример https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=1a19b0f5a7ba08c5e9dbb0cbf85d2a27

0 голосов
/ 03 мая 2020

Я думаю, что ваша проблема связана с тем, что таблица grn является вашей исходной таблицей, поэтому выборка получает строку для каждой строки в таблице. Сделайте material_table вашей первой таблицей и присоедините остальные к ней, используя ее идентификатор для объединения с остальными таблицами.

Pls, попробуйте эту версию и дайте мне знать, если она работает должным образом (возможно, содержат ошибку, я записал ее в блокнот)

SELECT sm.material_name as 'Material Name', mu.material_unit as 'Material Unit', sum(g.qty) as 'GRN Qty', sum(c.qty) as 'Consumed Qty', SUM(g.qty) - SUM(c.qty) as 'Stock' 
FROM material_table sm 
JOIN grn g ON g.material_id = sm.id
JOIN material_unit_table mu ON g.unit_id = mu.id
JOIN consumption c ON c.material_id = sm.material_id
GROUP BY by sm.material_id

Надеюсь, это поможет!

...