2015-11-02 59 views
1

我有一张表'Leistung'(意思是英语活动),一个表用于给定数量的两个活动之间的匹配(benoetigt)。例如,ID 2的活动需要3个ID 3的活动。使用'WITH RECURSIVE'计算总价

每个活动(leistung)都有一个价格。

我现在想要计算所有活动(leistung)的总价格,包括适量儿童活动的价格。

这里是我的表与一些TESTDATA:

CREATE TABLE Leistung (
    lnr INTEGER PRIMARY KEY, 
    bezeichnung VARCHAR(100) NOT NULL, 
    price NUMERIC(7,2) NOT NULL 
); 

CREATE TABLE benoetigt (
    lnr INTEGER REFERENCES Leistung(lnr), 
    benoetigt_lnr INTEGER REFERENCES Leistung(lnr), 
    amount INTEGER NOT NULL, 
    PRIMARY KEY (lnr,benoetigt_lnr) 
); 

INSERT INTO Leistung(lnr, bezeichnung, price) VALUES 
    (1, 'Discokugel', 100), 
    (2, 'Strobolicht', 100), 
    (3, 'Verstärker', 90), 
    (4, 'Gelaender',50), 
    (5, 'Bühne',50), 
    (6, 'Bühnenelement',20), 
    (7, 'Stromverteiler', 40), 
    (8, 'Stromkabel', 20); 

INSERT INTO benoetigt (lnr, benoetigt_lnr, amount) VALUES 
    (5,6,12), 
    (1,7,1), 
    (2,7,1), 
    (7,8,1); 

我非常舒尔的解决方案只能用 'WITH RECURSIV' 查询工作。 我第一次尝试这样IST:

WITH RECURSIVE benoetigtlist(lnr,benoetigt_lnr,menge) AS (
    SELECT lnr, benoetigt_lnr, menge FROM benoetigt 
    UNION ALL 
    SELECT b.lnr, b.benoetigt_lnr, b.menge 
    FROM benoetigtlist bl, benoetigt b 
    WHERE b.lnr = bl.benoetigt_lnr 
) 
SELECT * FROM benoetigtlist; 

但我不知道我怎么可以让这样的结果之间的联系与来自activitys定价。

或者这是错误的尝试?

下面是从TESTDATA为更好地了解SQL小提琴:SQL Fiddle

编辑:所需的输出是与总价所有activitys,包括他们的子女的价格清单。

对于结果上面的TESTDATA应该看起来像:

id text   price 
1 'Discokugel'  160 // 100 + 1*40 + 1*20 
2 'Strobolicht' 160 // 100 + 1*40 + 1*20 
3 'Verstärker'  90 
4 'Gelaender'  50 
5 'Bühne'   290 // 50 + 12*20 
6 'Bühnenelement' 20 
7 'Stromverteiler' 60 // 40 + 1*20 
8 'Stromkabel'  20 

例如与ID 5“Bühne”的活性具有290总的价格,因为intself成本50.同样在该活动需要的活性第6项活动(花费20)(根据'benoetigt'中的第一项)。

总结:50 + 12 * 20 = 290

在为重复标记质疑递归只发生在一个表中。但我有问题,价格信息是在另一个表中。

+0

该数据的期望输出是什么? –

+0

[在Postgres中使用sum进行递归查询]的可能重复(http://stackoverflow.com/questions/26660189/recursive-query-with-sum-in-postgres) –

+0

更新了所需输出的问题以及为什么它不是重复的。非常感谢。 – schw4ndi

回答

1

现在,你需要与你的活动表加入您的递归CTE的结果两次(一个连接来获得父母的价格,另一个加盟让孩子活动的价格)和组由父活动,总结子活动的成本:

WITH RECURSIVE benoetigtlist(lnr,benoetigt_lnr,menge) AS (
    SELECT lnr, benoetigt_lnr, amount 
    FROM benoetigt 
    UNION ALL 
    SELECT bl.lnr, b.benoetigt_lnr, b.amount 
    FROM benoetigtlist bl 
    , benoetigt b 
    WHERE b.lnr = bl.benoetigt_lnr 
) 
SELECT parent.lnr 
    , parent.bezeichnung 
    -- replace null with 0 if there are no child activities 
    , parent.price + COALESCE(children_cost.cost, 0) AS cost 
FROM Leistung parent 
-- subquery that summarizes total cost of all children: 
LEFT JOIN (
    SELECT bl.lnr, SUM(bl.menge * l.price) as cost 
    FROM benoetigtlist bl 
    INNER JOIN Leistung l on bl.benoetigt_lnr = l.lnr 
    GROUP BY bl.lnr 
) children_cost ON children_cost.lnr = parent.lnr 
ORDER BY parent.lnr