Re: Summing & Grouping in a Hierarchical Structure - Mailing list pgsql-sql
From | Don Parris |
---|---|
Subject | Re: Summing & Grouping in a Hierarchical Structure |
Date | |
Msg-id | CAJ-7yokLGhpPhYFDPnZ2akQbndBfZ0jEfA+O4LQHDHBcaG-kPg@mail.gmail.com Whole thread Raw |
In response to | Re: Summing & Grouping in a Hierarchical Structure (Bryan L Nuse <nuse@uga.edu>) |
Responses |
Re: Summing & Grouping in a Hierarchical Structure
|
List | pgsql-sql |
Hi Bryan,
My current (maybe about to be deprecated now) category table is a recursive table that I join on the line-item table. Your suggestion of using a table for each level of category is probably a bit easier to manage in some respects. However, as you pointed out, it becomes unwieldy when various branches of the category tree have different lengths. One effectively has to have the same number of levels in all branches. If only reality were so refined! :-) That is why I chose the recursive table structure that I gather is fairly common where the depth of a tree is not necessarily "even" or known.On Fri, Feb 22, 2013 at 11:54 PM, Bryan L Nuse <nuse@uga.edu> wrote:
<SNIP>Hello Don,Perhaps I am missing something about what your constraints are, or what you're trying to achieve, but is there any reason you could not use a series of joined tables indicating parent-child relationships? The following example follows that in your previous posts. Note that this approach (as given) will not work if branches stemming from the same node are different lengths. That is, if you have costs associated with "Transportation.Bicycle.Gear", you could not also have a category "Transportation.Bicycle.Gear.Chain_ring". (To add the latter category, you'd have to put costs from the former under something like "Transportation.Bicycle.Gear.General" -- or modify the approach.) However, lengthening the "Alcohol" branches, e.g., by tacking on a level5 table would be easy. Notice that level3 and level4 are not true look-up tables, since they may contain duplicate cat values.If I'm off base, by all means specify just how.Regards,Bryan--------------------------------------------------CREATE TABLE level1 (cat text PRIMARY KEY);CREATE TABLE level2 (cat text PRIMARY KEY,parent text REFERENCES level1(cat));CREATE TABLE level3 (cat text,parent text REFERENCES level2(cat),cost numeric(6,2));CREATE TABLE level4 (cat text,parent text,cost numeric(6,2));INSERT INTO level1VALUES ('Transportation'),('Groceries');INSERT INTO level2VALUES ('Auto', 'Transportation'),('Bicycle', 'Transportation'),('Fares', 'Transportation'),('Food', 'Groceries'),('Beverages', 'Groceries');INSERT INTO level3VALUES ('Fuel', 'Auto', 50.00),('Maintenance', 'Auto', 30.00),('Fuel', 'Auto', 25.00),('Gear', 'Bicycle', 40.00),('Gear', 'Bicycle', 20.00),('Bus', 'Fares', 10.00),('Train', 'Fares', 5.00),('Beverages', 'Food', 30.00),('Fruit_Veg', 'Food', 40.00),('Meat_Fish', 'Food', 80.00),('Grains_Cereals', 'Food', 30.00),('Alcohol', 'Beverages', NULL),('Juice', 'Beverages', 45.00),('Other', 'Beverages', 15.00);INSERT INTO level4VALUES ('Beer', 'Alcohol', 25.00),('Spirits', 'Alcohol', 10.00),('Wine', 'Alcohol', 50.00);CREATE VIEW all_cats AS (SELECT a.cat AS level4,b.cat AS level3,c.cat AS level2,d.cat AS level1,CASE WHEN a.cost IS NULL THEN 0WHEN a.cost IS NOT NULL THEN a.costEND+ CASE WHEN b.cost IS NULL THEN 0WHEN b.cost IS NOT NULL THEN b.costEND AS costFROM level4 aFULL JOINlevel3 bON (a.parent = b.cat)FULL JOINlevel2 cON (b.parent = c.cat)FULL JOINlevel1 dON (c.parent = d.cat)ORDER BY level1, level2, level3, level4);SELECT * FROM all_cats;level4 | level3 | level2 | level1 | cost---------+----------------+-----------+----------------+-------Beer | Alcohol | Beverages | Groceries | 25.00Spirits | Alcohol | Beverages | Groceries | 10.00Wine | Alcohol | Beverages | Groceries | 50.00| Juice | Beverages | Groceries | 45.00| Other | Beverages | Groceries | 15.00| Beverages | Food | Groceries | 30.00| Fruit_Veg | Food | Groceries | 40.00| Grains_Cereals | Food | Groceries | 30.00| Meat_Fish | Food | Groceries | 80.00| Fuel | Auto | Transportation | 50.00| Fuel | Auto | Transportation | 25.00| Maintenance | Auto | Transportation | 30.00| Gear | Bicycle | Transportation | 20.00| Gear | Bicycle | Transportation | 40.00| Bus | Fares | Transportation | 10.00| Train | Fares | Transportation | 5.00(16 rows)SELECT level1,count(cost) AS num_branches,sum(cost) AS total_costFROM all_catsGROUP BY level1ORDER BY level1;level1 | num_branches | total_cost----------------+--------------+------------Groceries | 9 | 325.00Transportation | 7 | 180.00(2 rows)
--
D.C. Parris, FMP, Linux+, ESL Certificate
Minister, Security/FM Coordinator, Free Software Advocate
GPG Key ID: F5E179BE