3

I have table like this:

id    activity            pay       parent   
1     pay all             -         null     
2     pay tax             10 $      1        
3     pay water bills     -         1        
4     fix house           -         null     
5     fix roof            1 $       4          
6     pay drinking water  1 $       3        

I want get table like this:

id    activity            pay       parent   matriks
1     pay all             {11 $}    null     1       (pay tax + pay water bills)
2     pay tax             10 $      1        1-2
3     pay water bills     {1 $}     1        1-3     (pay drinking water)
4     fix house           {1 $}     null     4       (fix roof)
5     fix roof            1 $       4        4-5     
6     pay drinking water  1 $       3        1-3-6

Count from child to parent: The problem is when water bills not counted from drinking water, pay all cant counted if pay tax or pay water not have pay value.

10
  • when you say table, you mean db or php? If db what RDBMS are you using? And what are those {}? Commented Jul 21, 2015 at 4:15
  • what is matriks ? What's your logic ? Commented Jul 21, 2015 at 4:15
  • @jWeaver In case of pay drinking water 1-3-6 i think is because add to row 1, 3 and 6 -- pay all, pay water, pay drinking Commented Jul 21, 2015 at 4:17
  • its like parent of 6 is 3,parent of 3 is 1 so 1-3-6 , he should have used 1->3->6 for clarity Commented Jul 21, 2015 at 4:20
  • @JuanCarlosOropeza i use postgre, {} value from child and this explained in right table, exp : pay water bills, it have child pay drinking water and have value 1 $, it counted to it parent (pay water bills) Commented Jul 21, 2015 at 5:58

1 Answer 1

2

I tried this on our postgres db (Version 8.4.22), since the fiddle was a bit slow for my taste. But the SQL can be pasted in there and it works for postgres.

Still here is the fiddle demo take like 20 sec first time but then is faster.

Here's what produces the calculated results for me. (I didn't format it according to your requirements, because in my mind the main excercise was the calculation.) This assumes your table is called activity:

with recursive rekmatriks as(
    select id, activity, pay, parent, id::text as matriks, 0 as lev
        from activity
        where parent is null
    union all
    select activity.id, activity.activity, activity.pay, activity.parent,
           rekmatriks.matriks || '-' || activity.id::text as matriks,
           rekmatriks.lev+1 as lev
        from activity inner join rekmatriks on activity.parent = rekmatriks.id
)
, reksum as (
    select id, activity, pay, parent, matriks, lev, coalesce(pay,0) as subsum
        from rekmatriks
        where not exists(select id from rekmatriks rmi where rmi.parent=rekmatriks.id)
    union all
    select rekmatriks.*, reksum.subsum+coalesce(rekmatriks.pay, 0) as subsum
        from rekmatriks inner join reksum on rekmatriks.id = reksum.parent)

select id, activity, pay, parent, matriks, sum(subsum) as amount, lev
    from reksum
group by id, activity, pay, parent, matriks, lev
order by id

As a bonus, this delivers the nesting depth of an id. 0 for a parent, 1 for first sublevel etc. This uses two recursive WITH queries to achieve what you want. The calculated value you need is in the amount column.

The first one (rekmatriks) processes the IDs in the table top to bottom, starting with any ids that have a parent of NULL. The recursive part simply takes the parent id and adds it's own id to it, to achieve your matriks tree representation field.

The second one (reksum) works bottom to top and starts with all rows that have no child elements. The recursive part of this query selects a parent row for each child row selected in the non-recursive part, and computes the sum of pay and subsum for each line. This produces multiple rows per id, since one parent can have multiple children.

All that's left now is the final select statement. It uses GROUP BY and SUM to aggregate the multiple possible child sum values into one row.

This does work for your particular example. It may fail if there's different cases not shown in the sample data, for example, if an item that has children carries a value that needs to be added.

Sign up to request clarification or add additional context in comments.

2 Comments

Very good. The only thing is format, dont know if OP is very strict on put pay as {10 $} and matriks as 1 (pay tax + pay water bills)
oh ...great, that solve my problem !! thanks all,, thanks @takrl

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.