Как сложить из связанной таблицы - PullRequest
0 голосов
/ 09 января 2019

У меня есть основная таблица и дополнительная таблица. Главная таблица - это основной список деталей, подтаблица - это коллективные части, необходимые для ее построения. Каждая дочерняя часть связана с родительской частью через ParentID.

Деталь или 'child' имеет ChildID, который указывает на свою собственную запись в основном списке деталей. Мы используем эту ссылку, чтобы узнать цену, так как внутри подтаблицы хранится только идентификатор.

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

Общая стоимость должна быть вычисляемым полем, которое выбирает все части в подтаблице, которые имеют ParentID == к своему идентификатору, и суммирует их цену * Кол-во.

Вот что у меня есть:

//This Query Doesnt work. Just returns 0.
SELECT SUM(PricePer * Qty)
    FROM sub inner join main on sub.ChildPID = main.ID where sub.ParentPID = main.ID

//This query will work, where the main.ID is entered manually. but I cant do this
SELECT SUM(PricePer * Qty)
    FROM sub inner join main on sub.ChildPID = main.ID where sub.ParentPID = 1

ПРИМЕР:

Основной стол

ID | Name | TotalCost | PricePer 

1    Part1  10.00       14.00**   SELECTED

2    Part2  0.00        6.00

3    Part3  0.00        2.00

Подстолье

ParentID | ChildID | Name | Qty

1          2         Part2  1

1          3         Part3  2

Ответы [ 3 ]

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

Вот выбор для одного уровня:

SELECT m.priceper + SUM(s1.qty * m2.priceper) AS priceper
FROM main m
LEFT JOIN sub s1 ON (m.id = s1.parentid)
LEFT JOIN main m2 ON (m2.id = s1.childid)
-- WHERE m.id = 1
GROUP BY m.id;

Для 2-х уровней это будет что-то вроде этого (я не мог попробовать, возможно, нужно исправить):

SELECT m1.id, m1.priceper + IFNULL(SUM(s1.qty * g2.priceper),0) AS priceper
FROM main m1
LEFT JOIN sub s1 ON (m1.id = s1.parentid)
LEFT JOIN (
    SELECT m2.id, m2.priceper + IFNULL(SUM(s2.qty * g2.priceper),0) AS priceper
    FROM main m2
    LEFT JOIN sub s2 ON (m2.id = s2.parentid)
    LEFT JOIN main g2 ON (g2.id = s2.childid)
    GROUP BY m2.id)
g2 ON (g2.id = s1.childid)
-- WHERE m1.id = 1
GROUP BY m1.id;

Для детализации необходимо заменить основную таблицу подзапросом для g3 и т. Д. *

SELECT m1.id, m1.priceper + IFNULL(SUM(s1.qty * g2.priceper),0) AS priceper
FROM main m1
LEFT JOIN sub s1 ON (m1.id = s1.parentid)
LEFT JOIN (
    SELECT m2.id, m2.priceper + IFNULL(SUM(s2.qty * g2.priceper),0) AS priceper
    FROM main m2
    LEFT JOIN sub s2 ON (m2.id = s2.parentid)
    LEFT JOIN (
        SELECT m3.id, m3.priceper + IFNULL(SUM(s3.qty * g3.priceper),0) AS priceper
        FROM main m3
        LEFT JOIN sub s3 ON (m3.id = s3.parentid)
        LEFT JOIN main g3 ON (g3.id = s3.childid)
        GROUP BY m3.id) g2 
        ON (g2.id = s2.childid)
    GROUP BY m2.id) g2 
    ON (g2.id = s1.childid)
-- WHERE m1.id = 1
GROUP BY m1.id;

Для 4 уровней это выглядит так:

SELECT m1.id, m1.priceper + IFNULL(SUM(s1.qty * g2.priceper),0) AS priceper
FROM main m1
LEFT JOIN sub s1 ON (m1.id = s1.parentid)
LEFT JOIN (
    SELECT m2.id, m2.priceper + IFNULL(SUM(s2.qty * g2.priceper),0) AS priceper
    FROM main m2
    LEFT JOIN sub s2 ON (m2.id = s2.parentid)
    LEFT JOIN (
        SELECT m3.id, m3.priceper + IFNULL(SUM(s3.qty * g3.priceper),0) AS priceper
        FROM main m3
        LEFT JOIN sub s3 ON (m3.id = s3.parentid)
        LEFT JOIN (
            SELECT m4.id, m4.priceper + IFNULL(SUM(s4.qty * g4.priceper),0) AS priceper
            FROM main m4
            LEFT JOIN sub s4 ON (m4.id = s4.parentid)
            LEFT JOIN main g4 ON (g4.id = s4.childid)
            GROUP BY m4.id) g3
        ON (g3.id = s3.childid)
        GROUP BY m3.id) g2 
        ON (g2.id = s2.childid)
    GROUP BY m2.id) g2 
    ON (g2.id = s1.childid)
-- WHERE m1.id = 1
GROUP BY m1.id;
0 голосов
/ 09 января 2019

Это стало более запутанным, чем я думаю. Может быть, я виновата в том, что не разъяснила это. Вот решение, которое я нашел, которое сработало.

Select *, ifnull((SELECT SUM(main.PricePer * Qty)
    FROM sub inner join main on sub.ChildID = main.ID where sub.ParentID = main1.PID), 0) from main as main1
0 голосов
/ 09 января 2019

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

Вы можете напрямую .. выполнить обновление на основе объединенного результата, например:

update main  
inner join  (
  SELECT  main.ID, SUM(main.PricePer) total_x_id
  FROM sub 
  INNER  join main on sub.ChildID = main.ID
  group by main.ID 
) t on t.id = main.id 
set total = t.total_x_id 

если вам просто нужно выбрать, то

 SELECT  main.ID, SUM(main.PricePer) total_x_id
 FROM sub 
 INNER  join main on sub.ChildID = main.ID
 group by main.ID 

вы можете получить результат в верхнем запросе, используя объединение как

select  maint.id, ifnull(t.total_x_id ,0)
from main 
left  join (
  SELECT  ChildID.ID as ID, SUM(main.PricePer) total_x_id
  FROM sub 
  group by ChildID.ID 
) t  on t.ID = main.id 
...