Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 General SQL Server Forums
 New to SQL Server Programming
 Sum Question

Author  Topic 

flamblaster
Constraint Violating Yak Guru

384 Posts

Posted - 2008-06-26 : 16:01:51
I have a query I've written that works very well for my needs, however, I am not able to get totals by the date. I tried to remove the field from the select and group by clause that separates the results out (es.run), however, it does not properly sum the totals when I do this because the totals for the 'Time' oriented fields are dependent on that field. Please see the following:

SELECT
B.ldate,
es.run,
(SELECT top 1 tal.loginname
FROM trackeractionlog TAL
WHERE tal.actiondate=[date,Date]
AND tal.Trackaction='PASS/SCHEDULE'
GROUP BY tal.loginname
Order by COUNT (case when tal.trackaction='PASS/SCHEDULE' then 1 else 0 end) desc) as 'Login',
es.tripcount,
(max(Case when e.activity=1 and e.actualarrivetime>0 then e.actualdeparttime else null end) -
min(case when e.activity=0 and e.actualarrivetime>0 then e.actualarrivetime else null end))*1.0/3600 as 'Service Hours', sum(numspacespu) as Passengers,
(sum(numspacespu))/((max(Case when e.activity=1 and e.actualarrivetime>0 then e.actualdeparttime else null end) -
min(case when e.activity=0 and e.actualarrivetime>0 then e.actualarrivetime else null end))*1.0/3600) as 'Passengers per Service Hour'
from booking b
JOIN events e
On e.bookingid=b.bookingid
JOIN bookingactivity ba
ON ba.legid=e.legid
JOIN run es
ON es.schid=e.schid
and es.evstrid=e.evstrid

WHERE b.ldate=[date,Date]
and b.schedstatus in (1,2,3)
and es.providerid=1
and ba.passtype<>'sa'

group by b.ldate, es.run, es.tripcount

Order by b.ldate, es.run


SAMPLE RESULTS:


06-25-2008 101 name 14 4.69 15 3.20
06-25-2008 101A name 3 1.08 3 2.78
06-25-2008 104 name 14 5.77 19 3.30
06-25-2008 105 name 17 6.77 18 2.66
06-25-2008 106 name 14 5.41 15 2.77

Please let me know if you need more info

Thanks in advance!
Craig

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2008-06-27 : 00:47:59
you need totals of what field based on date?
Go to Top of Page

flamblaster
Constraint Violating Yak Guru

384 Posts

Posted - 2008-06-27 : 04:57:32
Sorry...it's 2 fields actually:

(max(Case when e.activity=1 and e.actualarrivetime>0 then e.actualdeparttime else null end) -
min(case when e.activity=0 and e.actualarrivetime>0 then e.actualarrivetime else null end))*1.0/3600 as 'Service Hours',
&
(sum(numspacespu))/((max(Case when e.activity=1 and e.actualarrivetime>0 then e.actualdeparttime else null end) -
min(case when e.activity=0 and e.actualarrivetime>0 then e.actualarrivetime else null end))*1.0/3600) as 'Passengers per Service Hour'
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2008-06-27 : 06:20:08
quote:
Originally posted by flamblaster

Sorry...it's 2 fields actually:

(max(Case when e.activity=1 and e.actualarrivetime>0 then e.actualdeparttime else null end) -
min(case when e.activity=0 and e.actualarrivetime>0 then e.actualarrivetime else null end))*1.0/3600 as 'Service Hours',
&
(sum(numspacespu))/((max(Case when e.activity=1 and e.actualarrivetime>0 then e.actualdeparttime else null end) -
min(case when e.activity=0 and e.actualarrivetime>0 then e.actualarrivetime else null end))*1.0/3600) as 'Passengers per Service Hour'



and which is the time dependent field?
Go to Top of Page

flamblaster
Constraint Violating Yak Guru

384 Posts

Posted - 2008-06-27 : 11:21:09
Vis,
Both are time related. Here is an example of what I am looking for:

Each scheduled vehicle (es.run) has to push a button called 'Arrive' (e.actualarrivetime) when they get to a location. Then the push a button called 'Depart' (e.actualdeparttime) when they leave the location. In my initial query, I take the last depart time of the day(per run) and subtract the first arrive time of the day (per run) from that to get 'Service Hours'.

The second field divides the results of that field by the number of passengers (numspacespu), so it is time dependent as well.

As I said earlier, the report works very well when evaluating individual runs (es.run), but the way I have the query written, if I take es.run out of the select statement and group by clause, it will not calculate the individual runs to give me a total for the day. This does make sense to me, I just can't figure out a work around.

Thanks!
Craig
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2008-06-27 : 12:00:28
Try like this:-
SELECT *
FROM
(SELECT
B.ldate,
es.run,
(SELECT top 1 tal.loginname
FROM trackeractionlog TAL
WHERE tal.actiondate=[date,Date]
AND tal.Trackaction='PASS/SCHEDULE'
GROUP BY tal.loginname
Order by COUNT (case when tal.trackaction='PASS/SCHEDULE' then 1 else 0 end) desc) as 'Login',
es.tripcount,
(max(Case when e.activity=1 and e.actualarrivetime>0 then e.actualdeparttime else null end) -
min(case when e.activity=0 and e.actualarrivetime>0 then e.actualarrivetime else null end))*1.0/3600 as 'Service Hours', sum(numspacespu) as Passengers,
(sum(numspacespu))/((max(Case when e.activity=1 and e.actualarrivetime>0 then e.actualdeparttime else null end) -
min(case when e.activity=0 and e.actualarrivetime>0 then e.actualarrivetime else null end))*1.0/3600) as 'Passengers per Service Hour',0 as Seq
from booking b
JOIN events e
On e.bookingid=b.bookingid
JOIN bookingactivity ba
ON ba.legid=e.legid
JOIN run es
ON es.schid=e.schid
and es.evstrid=e.evstrid

WHERE b.ldate=[date,Date]
and b.schedstatus in (1,2,3)
and es.providerid=1
and ba.passtype<>'sa'

group by b.ldate, es.run, es.tripcount

UNION ALL

SELECT
B.ldate,
'Total',
(SELECT top 1 tal.loginname
FROM trackeractionlog TAL
WHERE tal.actiondate=[date,Date]
AND tal.Trackaction='PASS/SCHEDULE'
GROUP BY tal.loginname
Order by COUNT (case when tal.trackaction='PASS/SCHEDULE' then 1 else 0 end) desc) as 'Login',
es.tripcount,
(max(Case when e.activity=1 and e.actualarrivetime>0 then e.actualdeparttime else null end) -
min(case when e.activity=0 and e.actualarrivetime>0 then e.actualarrivetime else null end))*1.0/3600 as 'Service Hours', sum(numspacespu) as Passengers,
(sum(numspacespu))/((max(Case when e.activity=1 and e.actualarrivetime>0 then e.actualdeparttime else null end) -
min(case when e.activity=0 and e.actualarrivetime>0 then e.actualarrivetime else null end))*1.0/3600) as 'Passengers per Service Hour',1
from booking b
JOIN events e
On e.bookingid=b.bookingid
JOIN bookingactivity ba
ON ba.legid=e.legid
JOIN run es
ON es.schid=e.schid
and es.evstrid=e.evstrid

WHERE b.ldate=[date,Date]
and b.schedstatus in (1,2,3)
and es.providerid=1
and ba.passtype<>'sa'

group by b.ldate)t

Order by t.ldate,t.seq, t.run
Go to Top of Page

flamblaster
Constraint Violating Yak Guru

384 Posts

Posted - 2008-06-27 : 13:41:57
Thanks Vis,

That returned a duplicate row for each row that the first report was returning. The only difference was that the first row now has a value of 0 for the SEQ column and the second row has a value of 1 for the SEQ column.

Thanks!
Craig
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2008-06-28 : 04:03:54
quote:
Originally posted by flamblaster

Thanks Vis,

That returned a duplicate row for each row that the first report was returning. The only difference was that the first row now has a value of 0 for the SEQ column and the second row has a value of 1 for the SEQ column.

Thanks!
Craig


but wasnt that your requirement. just return rows giving total for each date along with your current figures.
Go to Top of Page

flamblaster
Constraint Violating Yak Guru

384 Posts

Posted - 2008-06-28 : 12:56:46
Hi Vis,

Sorry, no....I understand a lot of this stuff but I sometimes have a hard time communicating the requirements in writing. I actually just want to see
the total for the day...For example, if it were possible to group by the date and leave out the run from the group, that would be my ultimate goal...the problem I have
is that if I group by the day and leave out the run, I don't know how to tally the individual runs into one SUM...the reason for this is that the MIN() and MAX() portions of the query are evaluating the earliest time of the day period...In a perfect world, I would alias the Run table to the individual runs so that I could get each individual MIN and MAX, but I can never forsee what the run names will be or which will be used. Hope this makes sense.
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2008-06-28 : 13:45:17
quote:
Originally posted by flamblaster

Hi Vis,

Sorry, no....I understand a lot of this stuff but I sometimes have a hard time communicating the requirements in writing. I actually just want to see
the total for the day...For example, if it were possible to group by the date and leave out the run from the group, that would be my ultimate goal...the problem I have
is that if I group by the day and leave out the run, I don't know how to tally the individual runs into one SUM...the reason for this is that the MIN() and MAX() portions of the query are evaluating the earliest time of the day period...In a perfect world, I would alias the Run table to the individual runs so that I could get each individual MIN and MAX, but I can never forsee what the run names will be or which will be used. Hope this makes sense.


so as of your explanation, i guess what you need is totals for a date and also all the run values for the day (may be as a comma seperated list). Is that what you desire?
Go to Top of Page

flamblaster
Constraint Violating Yak Guru

384 Posts

Posted - 2008-06-28 : 15:08:10
Hi Vis,

What I would like is to eliminate the individual run values from the day and only show the total value for all the runs for the day.
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2008-06-29 : 02:23:58
quote:
Originally posted by flamblaster

Hi Vis,

What I would like is to eliminate the individual run values from the day and only show the total value for all the runs for the day.


If thats the case all you need to do is to remove run field from group by.
Go to Top of Page

flamblaster
Constraint Violating Yak Guru

384 Posts

Posted - 2008-06-29 : 04:25:44
Hmmm...I've tried that, but that was my original dilemma. When I take Run out of the group by clause, it doesn't tally all the fields...here's why:

Take for example we have 2 runs; Run A & Run B.

On MIN(e.activity=0), RUN A has an e.actualarrivetime of 0800
RUN B has an e.actualarrivetime of 0830

On MAX(e.activity=1) RUN A has an e.actualdeparttime of 1700
RUN B has an e.actualdeparttime of 1730

When I have the run in the group by clause, then query tallies the 1730-0830 and 1700-0800 to produce the results I need.
However, when I take the Run out of the group by clause, what I wind up with is 1730-0800 which is not the total of all the
runs for the day.

What I would like is the following scenario: (1730-0830) + (1700-0800)= 18
Go to Top of Page

flamblaster
Constraint Violating Yak Guru

384 Posts

Posted - 2008-06-29 : 04:37:02
By the way, it would be impractical for me to alias he run table multiple times because I won't ever know what the run
names will be in advance. (Example run es, run es1, run es2, run es3 etc will not work because the es.run field will always change)
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2008-06-29 : 05:08:51
Is this what you want?
SELECT 
B.ldate,
'Total',
(SELECT top 1 tal.loginname
FROM trackeractionlog TAL
WHERE tal.actiondate=[date,Date]
AND tal.Trackaction='PASS/SCHEDULE'
GROUP BY tal.loginname
Order by COUNT (case when tal.trackaction='PASS/SCHEDULE' then 1 else 0 end) desc) as 'Login',
es.tripcount,
(sum(Case when e.activity=1 and e.actualarrivetime>0 then e.actualdeparttime else null end) -
sum(case when e.activity=0 and e.actualarrivetime>0 then e.actualarrivetime else null end))*1.0/3600 as 'Service Hours', sum(numspacespu) as Passengers,
(sum(numspacespu))/((sum(Case when e.activity=1 and e.actualarrivetime>0 then e.actualdeparttime else null end) -
sum(case when e.activity=0 and e.actualarrivetime>0 then e.actualarrivetime else null end))*1.0/3600) as 'Passengers per Service Hour'
from booking b
JOIN events e
On e.bookingid=b.bookingid
JOIN bookingactivity ba
ON ba.legid=e.legid
JOIN run es
ON es.schid=e.schid
and es.evstrid=e.evstrid

WHERE b.ldate=[date,Date]
and b.schedstatus in (1,2,3)
and es.providerid=1
and ba.passtype<>'sa'

group by b.ldate

Order by b.ldate, es.run
Go to Top of Page

flamblaster
Constraint Violating Yak Guru

384 Posts

Posted - 2008-06-29 : 20:18:45
Hi Vis...thanks for all your help...it is VERY close...I'll play with the query a bit to tweak and see where I'm going wrong...there's about a 2% error rate with the returned results, but I'm sure it's something on my end. Thanks for sticking with me...not quite sure why I didn't try this the first time...I've used this format before...just didn't click. Thanks again! Craig
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2008-06-29 : 23:46:00
quote:
Originally posted by flamblaster

Hi Vis...thanks for all your help...it is VERY close...I'll play with the query a bit to tweak and see where I'm going wrong...there's about a 2% error rate with the returned results, but I'm sure it's something on my end. Thanks for sticking with me...not quite sure why I didn't try this the first time...I've used this format before...just didn't click. Thanks again! Craig


No probs...Come back if you face any probs.. Cheers
Go to Top of Page

flamblaster
Constraint Violating Yak Guru

384 Posts

Posted - 2008-07-01 : 04:32:02
Hi Vis,

Sorry to rehash this, I was going over the query and realized that you took the min and max out. I'm pretty sure that's why I'm not getting the intended results.
Here's a simplified example of what I'm trying to achieve with corresponding data:

Data Set:

b.dat es.run e.act e.arr e.dep
5/5/08 101 0 800 805
" " 1 900 905
" " 0 930 935
" " 1 1000 1005
5/5/08 102 0 900 905
" " 1 1200 1230
" " 0 1245 1350
" " 1 1400 1500
Select B.Dat,
Max(case when e.act=1 then e.dep else null end) -
Min(case when e.act=0 then e.arr else null end) as 'SvcHr'

From Booking B
JOIN Events E
ON b.bookingid=e.bookingid
JOIN RUN ES
ON es.schid=e.schid
AND es.evstrid=e.evstrid
WHERE b.date=?

Group by b.date

What I need to calculate is the total of the max(case when e.act=1 then e.dep else null end) - Min(case when e.act=0 then e.arr else null end In the above example this would be 1005-0800 and 1500-900.

THe problem I have is that I don't know how to sum the max-min. I know I can't do this, but I think it would look like this the way I'm thinking of it:

Sum(Max(case when e.act=1 then e.dep) - Min(case when e.act=0 then e.arr))

I realize you can't aggregate an aggregate, but this is essentially what I want to achieve. So that I can get the total of the separate runs.

Any other thoughts?

Thanks!
Craig
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2008-07-01 : 04:42:35
quote:
Originally posted by flamblaster

Hi Vis,

Sorry to rehash this, I was going over the query and realized that you took the min and max out. I'm pretty sure that's why I'm not getting the intended results.
Here's a simplified example of what I'm trying to achieve with corresponding data:

Data Set:

b.date es.run e.activity e.arrivetime e.departtime min(e.arrive) max(e.departtime) Service Hours
5/5/2008 101 0 800 805 800 ---- -----
" 1 900 905 ---- ---- ----
0 930 935 ---- ---- ----
1 1000 1005 1005 1005-0800

102 0 1000 1020 1000 ---- ----
1 1030 1035 ---- ---- ----
0 1300 1400 ---- ---- ----
1 1500 1520 ---- 1520 1520-1000



Select B.Date,
Max(case when e.activity=1 then e.departtime else null end) -
Min(case when e.activity=0 then e.arrivetime else null end) as 'Total Service Hours'

From Booking B
JOIN Events E
ON b.bookingid=e.bookingid
JOIN RUN ES
ON es.schid=e.schid
AND es.evstrid=e.evstrid
WHERE b.date=?

Group by b.date

Without the Min and Max, I could end up with 935-930 on Run 101 and 1400-1300 on Run 102. But putting Min for all the runs and Max for all the runs doesn't give me the result I want either if grouping by es.run because it will give me the latest departtime of the day and subtract the earliest arrivetime of the day from it.

Any other thoughts?

Thanks!
Craig



if thats the case why are you thinking of taking out run from group by?your requirement suggets you want max & min datetimes for each run value which really asks for it to be included in group by.
Go to Top of Page

flamblaster
Constraint Violating Yak Guru

384 Posts

Posted - 2008-07-01 : 04:49:07
Yes, that's exactly it...what I'm hoping for is to be able to see the total of the day for large date ranges without seeing all the details of each day.
Hopefully my edits to my post will make sense...
Go to Top of Page

visakh16
Very Important crosS Applying yaK Herder

52326 Posts

Posted - 2008-07-01 : 04:59:01
quote:
Originally posted by flamblaster

Yes, that's exactly it...what I'm hoping for is to be able to see the total of the day for large date ranges without seeing all the details of each day.
Hopefully my edits to my post will make sense...


you can add a derived table in your query to get max and min for each run and then use it in main query joining on run value.
Go to Top of Page
    Next Page

- Advertisement -