Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6342231
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 24, 20262026-05-24T20:12:06+00:00 2026-05-24T20:12:06+00:00

I have a table containing stages and sub-stages of certain projects, and a table

  • 0

I have a table containing stages and sub-stages of certain projects, and a table with specific tasks and estimated costs.
I need some way to aggregate each level (stages/sub-stages), to see how much it costs, but to do it at a minimum performance cost.

To illustrate this, I will use the following data structure:

CREATE TABLE stage
(
    id int not null,
    fk_parent int
)

CREATE TABLE task
(
    id int not null,
    fk_stage int not null,
    cost decimal(18,2) not null default 0
)

with the following data:

==stage==
id  fk_parent
1   null
2   1
3   1

==task==
id  fk_stage  cost
1   2         100
1   2         200
1   3         600

I want to obtain a table containing the total costs on each branch. Something like this:

Stage ID      Total Cost
1             900
2             300
3             600

But, I also want it to be productive. I don’t want to end up with extremely bad solutions like The worst algorithm in the world. I mean this is the case. In case I’ll request the data for all the items in the stage table, with the total costs, each total cost will be evaluated D times, where D is the depth in the tree (level) at which it is situated. I am afraid I’ll hit extremely low performances at large amounts of data with a lot of levels.

SO,

I decided to do something which made me ask this question here.
I decided to add 2 more columns to the stage table, for caching.

...
calculated_cost decimal(18,2),
date_calculated_cost datetime
...

So what I wanted to do is pass another variable within the code, a datetime value which equals to the time when this process was started (pretty much unique). That way, if the stage row already has a date_calculated_cost which equals to the one I’m carrying, I don’t bother calculating it again, and just return the calculated_cost value.

I couldn’t do it with Functions (updates are needed to the stage table, once costs are calculated)
I couldn’t do it with Procedures (recursion within running cursors is a no-go)
I am not sure temporary tables are suitable because it wouldn’t allow concurrent requests to the same procedure (which are least likely, but anyway I want to do it the right way)
I couldn’t figure out other ways.

I am not expecting a definite answer to my question, but I will reward any good idea, and the best will be chosen as the answer.

  • 1 1 Answer
  • 3 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-24T20:12:08+00:00Added an answer on May 24, 2026 at 8:12 pm

    1. A way to query the tables to get the aggregated cost.

    1. Calculate the cost for each stage.
    2. Use a recursive CTE to get the level for each stage.
    3. Store the result in a temp table.
    4. Add a couple of indexes to the temp table.
    5. Update the cost in the temp table in a loop for each level

    The first three steps is combined to one statement. It might be good for performance to do the first calculation, cteCost, to a temp table of it’s own and use that temp table in the recursive cteLevel.

    ;with cteCost as
    (
      select s.id,
             s.fk_parent,
             isnull(sum(t.cost), 0) as cost
      from stage as s
        left outer join task as t
          on s.id = t.fk_stage
      group by s.id, s.fk_parent
    ),
    cteLevel as
    (
      select cc.id,
             cc.fk_parent,
             cc.cost,
             1 as lvl
      from cteCost as cc
      where cc.fk_parent is null
      union all
      select cc.id,
             cc.fk_parent,
             cc.cost,
             lvl+1
      from cteCost as cc
        inner join cteLevel as cl
          on cc.fk_parent = cl.id       
    )
    select *
    into #task
    from cteLevel
    
    create clustered index IX_id on #task (id)
    create index IX_lvl on #task (lvl, fk_parent)
    
    declare @lvl  int
    select @lvl = max(lvl)
    from #task
    
    while @lvl > 0
    begin
    
      update T1 set
        T1.cost = T1.cost + T2.cost
      from #task as T1
        inner join (select fk_parent, sum(cost) as cost
                    from #task
                    where lvl = @lvl
                    group by fk_parent) as T2
          on T1.id = T2.fk_parent
    
      set @lvl = @lvl - 1
    end
    
    select id as [Stage ID],
           cost as [Total Cost] 
    from #task
    
    drop table #task
    

    2. A trigger on table task that maintains a calculated_cost field in stage.

    create trigger tr_task 
    on task 
    after insert, update, delete
    as
      -- Table to hold the updates
      declare @T table
      (
        id int not null, 
        cost decimal(18,2) not null default 0
      )
    
      -- Get the updates from inserted and deleted tables
      insert into @T (id, cost)
      select fk_stage, sum(cost)
      from (
              select fk_stage, cost
              from inserted
              union all
              select fk_stage, -cost
              from deleted
           ) as T   
      group by fk_stage
    
      declare @id int
      select @id = min(id)
      from @T
    
      -- For each updated row
      while @id is not null
      begin
    
        -- Recursive update of stage
        with cte as 
        (
          select s.id,
                 s.fk_parent
          from stage as s
          where id = @id
          union all
          select s.id,
                 s.fk_parent
          from stage as s
            inner join cte as c
              on s.id = c.fk_parent    
        )
        update s set
          calculated_cost = s.calculated_cost + t.cost 
        from stage as s
          inner join cte as c
            on s.id = c.id
          cross apply (select cost
                       from @T
                       where id = @id) as t   
    
        -- Get the next id
        select @id = min(id)
        from @T
        where id > @id
      end
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a Table containing some information that I need. All these rows also
I have a table containing users... one way or another some users were doubled
I have a table containing data about some users. Many of them use our
I have a table containing some names and their associated ID, along with a
I have a table containing some datetime columns, now I want to get the
I have a table containing IP Address,timestamp and browser columns.I need to find the
I have a table containing some numeric columns, and i have to keep them
I have a table containing some categories Categories Table: -- category_id <-- primary key
I have a table containing some Timespans (as two TIME columns) Eg: TimeBegin TimeEnd
I have a table containing typical hierarchical data for tasks with an arbitrary level

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.