Solved

SQL 2008 - Running total partition over Company - for each grouping per Company - run total else reset

Posted on 2013-06-25
13
400 Views
Last Modified: 2013-06-25
Hi, I spent a lot of time looking through a lot of results on google, but can't get exactly what I need even after changing many methods of the examples

 
Drop Table #Checks
CREATE TABLE #Checks
(
  Client VARCHAR(32),
  RowNr int,
  Amount DECIMAL(12,2)
);

INSERT #Checks(Client, RowNr, Amount)
          SELECT 'Company A', '1', 50
UNION ALL SELECT 'Company A', '2', 75
UNION ALL SELECT 'Company A', '3', 120
UNION ALL SELECT 'Company B', '4', 75
UNION ALL SELECT 'Company A', '5', 40
UNION ALL SELECT 'Company B', '6', 200
UNION ALL SELECT 'Company B', '7', 90;

Open in new window


select * from #checks
I need help on getting it to (Sort by RowNumber) and reset whenever a company changes please. Thus

Company A Running Total 50
Company A Running Total 125
Company A Running Total 245
Company B Running Total 75
Company A Running Total 40
Company B Running Total 200
Company B Running Total 290

Open in new window

0
Comment
Question by:jxharding
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 8
  • 5
13 Comments
 
LVL 49

Expert Comment

by:PortletPaul
ID: 39274018
have you tried the row_number() analytic function?
0
 

Author Comment

by:jxharding
ID: 39274023
Hi, Row_Number() was used previously yes, any hint on how to use it in this scenario? The RowNumbers are already generated?
0
 
LVL 49

Expert Comment

by:PortletPaul
ID: 39274033
this is a quick reply, using a cte to simulate the temp table - but using row_number() to re- sequence the output.
CLIENT	AMOUNT	ROWNR
Company A	50	1
Company A	75	2
Company A	120	3
Company A	40	4
Company B	75	1
Company B	200	2
Company B	90	3


with #checks (client, RowNr, Amount)  as (
                      SELECT 'Company A', '1', 50
            UNION ALL SELECT 'Company A', '2', 75
            UNION ALL SELECT 'Company A', '3', 120
            UNION ALL SELECT 'Company B', '4', 75
            UNION ALL SELECT 'Company A', '5', 40
            UNION ALL SELECT 'Company B', '6', 200
            UNION ALL SELECT 'Company B', '7', 90
            ),
rechecks as (
              select
                 client
               , amount
               , row_number() over (partition by client order by rownr) as rownr
              from #checks
            )
select
*
from rechecks
order by client, RowNr
;

Open in new window

see http://sqlfiddle.com/#!3/1fa93/7924
0
Ransomware-A Revenue Bonanza for Service Providers

Ransomware – malware that gets on your customers’ computers, encrypts their data, and extorts a hefty ransom for the decryption keys – is a surging new threat.  The purpose of this eBook is to educate the reader about ransomware attacks.

 
LVL 49

Expert Comment

by:PortletPaul
ID: 39274043
>>any hint on how to use it in this scenario? The RowNumbers are already generated?
I hope my previous post answers this

it's really up to you, but I would suggest
row_number() over (partition by client order by RowNr) as <<something you choose>>

the 'partition by client' will re-start the numbers for each client, &
the 'order by rowNr' will leverage the wanted sequence

you can give this calculated column a different alias - i just re-used rowNr above.
0
 

Author Comment

by:jxharding
ID: 39274047
Thanks, I think we missed each other on this one unfortunately. I'd like to keep the existing row numbers, and create a running total for each company, until the company changes, which then resets the running total -
e.g.

Company A (First case) Running Total 50
Company A (First case) Running Total 125
Company A (First case) Running Total 245
Company B (Second case) Running Total 75
Company A (Third case) Running Total 40
Company B (Fourth case) Running Total 200
Company B (Fourth case) Running Total 290
0
 
LVL 49

Expert Comment

by:PortletPaul
ID: 39274048
Oh, and you don't have to use CTEs, let's assume you continue with the temp table, then it could look like this:
select
client, amount, rowNr, rowNr2
from (
              select
                 client
               , amount
               , rowNr
               , row_number() over (partition by client order by rownr) as rownr2
              from #checks
            ) as rechecks
from rechecks
order by client, RowNr2

Open in new window

0
 
LVL 49

Expert Comment

by:PortletPaul
ID: 39274051
running total ....my bad ... hold on ... most sorry
0
 
LVL 49

Expert Comment

by:PortletPaul
ID: 39274059
this is SQL Server 2008 - is that correct? (or is it 2012?)
0
 

Author Comment

by:jxharding
ID: 39274121
SQL Server 2008 yes please, thanks!
0
 
LVL 49

Accepted Solution

by:
PortletPaul earned 500 total points
ID: 39274378
mmm, not sure I can get this in 2008, this is NOT correct but its as close as I can get right now (in the sample provided the last number is wrong)
CLIENT	ROWNR	AMOUNT	RUNTOTAL
Company A	1	50	50
Company A	2	75	125
Company A	3	120	245
Company B	4	75	75
Company A	5	40	40
Company B	6	200	200
Company B	7	90	365 --<< wrong, 290 expected


-- with this code
with cte as (
            select
                    c1.client
                  , c1.amount
                  , c1.rowNr
                  , case when c1.client <> c2.client then c1.amount else null end amt
            from checks as c1
            left join checks as C2 on c1.rownr = (c2.rownr + 1)
  )

select
client
, rownr
, amount
, case when amt > 0 then amt else total end as runtotal
from cte
cross apply (
                select
                       sum(x.amount) as Total
    			from cte as x
    			where x.rownr <= cte.rownr and cte.client = x.client
    		) as rt
;

-- using this
CREATE TABLE Checks
(
  Client VARCHAR(32),
  RowNr int,
  Amount DECIMAL(12,2),
  RunTotal DECIMAL(12,2)
);

INSERT Checks(Client, RowNr, Amount)
          SELECT 'Company A', '1', 50
UNION ALL SELECT 'Company A', '2', 75
UNION ALL SELECT 'Company A', '3', 120
UNION ALL SELECT 'Company B', '4', 75
UNION ALL SELECT 'Company A', '5', 40
UNION ALL SELECT 'Company B', '6', 200
UNION ALL SELECT 'Company B', '7', 90;

Open in new window

0
 

Author Closing Comment

by:jxharding
ID: 39274390
This is brilliant, thank you very much! Will definitely be able to used this as an example! Thanks again!!
0
 
LVL 49

Expert Comment

by:PortletPaul
ID: 39274393
are you sure? it's NOT fully correct
0
 

Author Comment

by:jxharding
ID: 39274398
I'm sure i'll be able to battle out the last one, way better than anything I was able to get, thank you again!
0

Featured Post

Want Experts Exchange at your fingertips?

With Experts Exchange’s latest app release, you can now experience our most recent features, updates, and the same community interface while on-the-go. Download our latest app release at the Android or Apple stores today!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Naughty Me. While I was changing the database name from DB1 to DB_PROD1 (yep it's not real database name ^v^), I changed the database name and notified my application fellows that I did it. They turn on the application, and everything is working. A …
This article explains how to reset the password of the sa account on a Microsoft SQL Server.  The steps in this article work in SQL 2005, 2008, 2008 R2, 2012, 2014 and 2016.
Michael from AdRem Software outlines event notifications and Automatic Corrective Actions in network monitoring. Automatic Corrective Actions are scripts, which can automatically run upon discovery of a certain undesirable condition in your network.…
This is my first video review of Microsoft Bookings, I will be doing a part two with a bit more information, but wanted to get this out to you folks.

617 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question