我有两张表,其定义如下:
CREATE TABLE Parts (
id INTEGER PRIMARY KEY,
Name TEXT,
Quantity INTEGER,
Parentid INTEGER
);
CREATE TABLE Weight(
Name TEXT,
Weight INTEGER
);
“零件”表包含父零件和子零件的行。
对于产品A,有几个部分(B1和B2)和子部分(C1-C4):
内容如下:
A:2xB1,2xB2,1xC1,5xC2
B1:3xC1,2xC2
B2:1xB1,1xC3
和重量之类的东西:
C1:5
C2:4
C3:2
...或:
╔════════════════════════════════════╗
║ Parts ║
╠═══════╦══════╦══════════╦══════════╣
║ id ║ Name ║ Quantity ║ Parentid ║
╠═══════╬══════╬══════════╬══════════╣
║ A ║ A ║ 1 ║ NULL ║
║ B1 ║ B1 ║ 2 ║ A ║
║ B2 ║ B2 ║ 2 ║ A ║
║ C1 ║ C1 ║ 1 ║ A ║
║ C2 ║ C2 ║ 5 ║ A ║
║ C1 ║ C1 ║ 3 ║ B1 ║
║ C2 ║ C2 ║ 2 ║ B1 ║
║ B1 ║ B1 ║ 1 ║ B2 ║
║ C3 ║ C3 ║ 1 ║ B2 ║
╚═══════╩══════╩══════════╩══════════╝
╔═════════════════╗
║ Weight ║
╠════════╦════════╣
║ Name ║ Weight ║
╠════════╬════════╣
║ C1 ║ 5 ║
║ C2 ║ 4 ║
║ C3 ║ 2 ║
║ C4 ║ 8 ║
╚════════╩════════╝
表中是子部件C1-C4的重量和每个部件的数量。 如何获得每个部件和整个产品的重量?
我知道它是递归CTE的东西,但我无法得到我想要的结果。 我在Recursive sum in tree structure的帮助下尝试了它但没有取得多大成功。
这就是我所拥有的:
WITH c as (
SELECT Parts.id,
Parts.quantity,
Parts.id as RootID,
(Parts.quantity * Weight.weight) as Weight
FROM Parts LEFT JOIN Weight ON Weight.name = Parts.name
UNION ALL
SELECT Parts.id,
Parts.quantity,
c.RootID,
(Parts.quantity * Weight.weight) as Weight
FROM Parts LEFT JOIN Weight on Weight.name = Parts.name
INNER JOIN c on Parts.Parentid = c.id
)
SELECT Parts.id,
Parts.parent,
Parts.name,
Parts.quantity,
S.SumWeight
FROM Parts INNER JOIN (
SELECT rootid,
SUM(weight) as SumWeight
FROM c
GROUP BY rootid
) as S on Parts.id = S.rootid
ORDER BY Parts.id
我想要达到的结果是:
A 121
B1 23
B2 25
感谢任何帮助!
答案 0 :(得分:0)
关于如何在设计中总结重量以避免重复包含重量,我们并不清楚,但这是使用与您建议的表格非常类似的表格进行递归的示例。
CREATE TABLE Parts (
Id varchar(20),
Name varchar(20),
Quantity INTEGER,
ParentId varchar(20)
);
CREATE TABLE Weight(
Name varchar(20),
[Weight] INTEGER
);
insert into Parts (Id, Name, Quantity, Parentid)
values ('A','A', 1, NULL),
('B1','B1', 2, 'A'),
('B2','B2', 2, 'A'),
('C1','C1', 1, 'A'),
('C2','C2', 5, 'A'),
('C1','C1', 3, 'B1'),
('C2','C2', 2, 'B1'),
('B1','B1', 1, 'B2'),
('C3','C3', 1, 'B2');
insert into Weight(Name, Weight)
values ('C1', 5),
('C2', 4),
('C3', 2),
('C4', 8);
WITH a as (
SELECT x.Id as EndId,
x.Id as ComponentId,
0 as ComponentQuantity,
1 as Lvl
FROM Parts x INNER JOIN Parts y ON x.Id = y.ParentId -- must have at least 1 child...
GROUP BY x.Id
UNION ALL
SELECT a.EndId,
x.Id as ComponentId,
x.Quantity as ComponentQuantity,
a.Lvl + 1 as Lvl
FROM Parts x INNER JOIN a ON x.ParentId = a.ComponentId
)
SELECT a.EndId,
SUM(a.ComponentQuantity) as SumQuantity,
SUM(a.ComponentQuantity * b.Weight) as SumWeight
FROM a INNER JOIN Weight b ON a.ComponentId = b.Name
WHERE a.EndId <> a.ComponentId
AND a.Lvl = 2 -- treat 1st child as the weighted subassembly of interest
GROUP BY a.EndId;