View Full Version : Totaling many columns for specified date ranges


shawnb777
02-19-2009, 12:38 PM
I have a database that is a pilot logbook. I have one table, it contains a record for each flight I have made. The first column is the date, and the rest of the columns are simple decimal columns which represent several breakdowns of a flight in terms of hours, i.e. Total duration of flight, Night flight, Day flight, Pilot in Command (PIC), Second in Command (SIC), etc. Here's a screenshot of a sample record from the database:

http://fermata.lrehosting.com/files/Picture 1.png

I would like to get an output of a bunch of these totals aggregated by date range. For example, I want a report that will tell me the Sum of Day, Sum of PIC, Sum of SIC within the past 30 days, 60 days, 90 days, 120 days, etc. I can do this by making a bunch of queries with subtotals for each of the required breakdowns, but I want it all in one output, here's a screenshot of what I mean (with some dummy data):

http://fermata.lrehosting.com/files/Picture 2.png

This is what I want, basically a spreadsheet-like output with all of the breakdowns.

Is there an easy way to do this? It almost looks like a Pivottable could work but I tried messing around with it and I couldn't find a way to aggregate based on custom date ranges. Thanks a lot.

jal
02-19-2009, 04:42 PM
I think you might can do this with a pivot table but you should probably start with a base query and then base the pivot table on that. Here's a base query (I'll assume your table is called Pilots. (I rushed this - so may be some syntax errors).

SELECT SUM(Pilots.PIC) as PIC, SUM(Pilots.Sic) as SIC, SUM(Pilots.XC) as XC, SUM(Pilots.Night) as Night, 'Last 30 Days' as Span
FROM Pilots
WHERE [Date] >= Date() - 30

UNION ALL

SELECT SUM(Pilots.PIC) as PIC, SUM(Pilots.Sic) as SIC, SUM(Pilots.XC) as XC, SUM(Pilots.Night) as Night, 'Last 60 Days' as Span
FROM Pilots
WHERE [Date] >= Date() - 60

UNION ALL

SELECT SUM(Pilots.PIC) as PIC, SUM(Pilots.Sic) as SIC, SUM(Pilots.XC) as XC, SUM(Pilots.Night) as Night, 'Last 90 Days' as Span
FROM Pilots
WHERE [Date] >= Date() - 90

UNION ALL

SELECT SUM(Pilots.PIC) as PIC, SUM(Pilots.Sic) as SIC, SUM(Pilots.XC) as XC, SUM(Pilots.Night) as Night, 'Last 120 Days' as Span
FROM Pilots
WHERE [Date] >= Date() - 120

shawnb777
02-19-2009, 07:41 PM
Thanks, that works!

shawnb777
02-20-2009, 09:51 AM
Is there any way to add an additional condition - I would like to make a column that is Night where PIC is greater than 0... in essence, return records where PIC time AND Night time has been logged.... in which we count only the time that is Night AND PIC. Ie. we have one flight that was PIC=2 and Night=1.2, so we only count the 1.2 (because it is both PIC and Night) and add it up like the other columns. Can we do this within the same SQL query? Thanks again

jal
02-20-2009, 01:28 PM
Is there any way to add an additional condition - I would like to make a column that is Night where PIC is greater than 0... in essence, return records where PIC time AND Night time has been logged.... in which we count only the time that is Night AND PIC. Ie. we have one flight that was PIC=2 and Night=1.2, so we only count the 1.2 (because it is both PIC and Night) and add it up like the other columns. Can we do this within the same SQL query? Thanks again I am not entirely sure this request is intelligible to a database.
The query I gave you already has a WHERE clause, it returns records where that condition is met. Now you seem to be speaking of a different WHERE clause which would seem to return a different set of records, possibly contradicting your first request. I'm feeling confused.

jal
02-20-2009, 03:04 PM
Maybe what you wanted is to add another section like this:

UNION ALL


SELECT SUM(Pilots.PIC) as PIC, SUM(Pilots.Sic) as SIC, SUM(Pilots.XC) as XC, SUM(Pilots.Night) as Night, 'WHEREVER PIC > 0 ' as Span
FROM Pilots
WHERE PIC > 0

shawnb777
02-21-2009, 06:50 AM
Yes, you are understanding correctly. That creates another row with only records where PIC > 0, but I would like to have instead of a row, a column (so that the date ranges are still factored in), see image:

http://fermata.lrehosting.com/files/Picture 6.png

Thanks a lot for your help!

jal
02-21-2009, 07:07 AM
Maybe I'm beginning to understand. I gave you four queries UNIONED. And I think you added one (for "Last Year") giving a total of five.

In that case add five queries resulting in 10 unioned queries. With the first five, the WHERE claus was like this:

WHERE [Date] >= Date() - 120

With the last five, the WHERE clause should probably be this:

WHERE [Date] >= Date() - 120 AND Pic > 0

shawnb777
02-21-2009, 07:14 AM
Can you append it to what I have already? I'm not sure what you mean by the "last five" and "first five"

jal
02-21-2009, 07:32 AM
The four queries I gave you are these:
30 days
60 days
90 days
120 days

You just uploaded a picture which has a fifth item
30 days
60 days
90 days
120 days
Last year
So I can only assume you added a fifth query. No?

shawnb777
02-21-2009, 07:37 AM
Yeah, you're right. I'll be adding a ton more of those queries. We can just consider it 4 for now to keep with the original example (I should be able to expand on it as necessary) right now I'm just trying to get that extra breakdown of Night where PIC > 0. To keep with the original example, here's what i'm looking for at this point:

http://fermata.lrehosting.com/files/Picture 6.png

jal
02-21-2009, 07:42 AM
Yes, then, as I said, union for more queries to the four I gave (only the WHERE clause will chaneg, as I said). Maybe I'll do it for you...

jal
02-21-2009, 07:43 AM
Or do I have that wrong. I'm getting confused again (as usual).

jal
02-21-2009, 07:45 AM
It's hard to do all this without sample data since I'm not all that bright. I usually get it right only by trial and error. I'll let you know if I can figure this out in my head.

jal
02-21-2009, 07:52 AM
I am guessing I gave you the right answer in post #8. If you don't follow me, maybe Ill write it out for you in full.

shawnb777
02-21-2009, 07:55 AM
Here is the output of the original code you gave me (Post #2), if that helps:

http://fermata.lrehosting.com/files/Picture 7.png

I just want to add another column that has Night where PIC > 0. So basically, we are constraining that information twice - across with the date ranges, and down with specifiying only records that have both PIC and Night.

shawnb777
02-21-2009, 07:56 AM
Post 8 may be right, I'd try it if you could write it for me, I am really new to SQL! D'oh!

jal
02-21-2009, 08:34 AM
Okay I think I was wrong. I think you need an inner join to add that column. (Join two queries). So I'll just write a second query and then I'll give you a suggestion on how to inner join the two queries.

jal
02-21-2009, 08:44 AM
Okay here's the second query

SELECT SUM(Pilots.Night) as [Night WHERE Pic > 0] , 'Last 30 Days' as Span
FROM Pilots
WHERE [Date] >= Date() - 30 AND Pic > 0

UNION ALL

SELECT SUM(Pilots.Night) as [Night WHERE Pic > 0] , 'Last 60 Days' as Span
FROM Pilots
WHERE [Date] >= Date() - 60 AND Pic > 0

UNION ALL

SELECT SUM(Pilots.Night) as [Night WHERE Pic > 0] , 'Last 90 Days' as Span
FROM Pilots
WHERE [Date] >= Date() - 90 AND Pic > 0

UNION ALL

SELECT SUM(Pilots.Night) as [Night WHERE Pic > 0] , 'Last 120 Days' as Span
FROM Pilots
WHERE [Date] >= Date() - 120 AND Pic > 0

Suppose you named the first query qrySumAll and this last one qrySumPicsAboveZero, you can now write a new query that joins them.

SELECT * FROM qrySumAll as Q1
INNER JOIN qrySumPicsAboveZero as Q2
ON Q1.Span = Q2.Span

The "Span" column returns twice, hope that's not a problem. I could eliminate that if necessary.

jal
02-21-2009, 09:33 AM
Just realized I could have done the whole thing in one query:

SELECT SUM(Pilots.PIC) as PIC, SUM(Pilots.Sic) as SIC, SUM(Pilots.XC) as XC, SUM(Pilots.Night) as Night, SUM(IIF(Pic > 0, Night, 0)) as [Night WHERE Pic > 0], 'Last 30 Days' as Span
FROM Pilots
WHERE [Date] >= Date() - 30

UNION ALL

SELECT SUM(Pilots.PIC) as PIC, SUM(Pilots.Sic) as SIC, SUM(Pilots.XC) as XC, SUM(Pilots.Night) as Night, SUM(IIF(Pic > 0, Night, 0)) as [Night WHERE Pic > 0], 'Last 60 Days' as Span
FROM Pilots
WHERE [Date] >= Date() - 60

UNION ALL

SELECT SUM(Pilots.PIC) as PIC, SUM(Pilots.Sic) as SIC, SUM(Pilots.XC) as XC, SUM(Pilots.Night) as Night,SUM(IIF(Pic > 0, Night, 0)) as [Night WHERE Pic > 0], 'Last 90 Days' as Span
FROM Pilots
WHERE [Date] >= Date() - 90

UNION ALL

SELECT SUM(Pilots.PIC) as PIC, SUM(Pilots.Sic) as SIC, SUM(Pilots.XC) as XC, SUM(Pilots.Night) as Night,SUM(IIF(Pic > 0, Night, 0)) as [Night WHERE Pic > 0], 'Last 120 Days' as Span
FROM Pilots
WHERE [Date] >= Date() - 120

shawnb777
02-21-2009, 09:43 AM
The second method returns an error "Subqueries cannot be used in the expression (Sum(IIF(Pic>0,Night,0)))" is it just a syntax error somewhere?

jal
02-21-2009, 10:00 AM
The second method returns an error "Subqueries cannot be used in the expression (Sum(IIF(Pic>0,Night,0)))" is it just a syntax error somewhere?
I don't know - in fact that's why I originally decided to use two separate queries, meaning i wasn't sure if Access allows this sort of thing. I'll try to figure that out.

jal
02-21-2009, 10:07 AM
I don't get it, that should have worked. Yes, it could be a syntax error but I don't see one as yet.

jal
02-21-2009, 10:12 AM
I just made a row of fake data and tried this:

SELECT SUM(IIF(Pic > 0, Night, 0)) as [Night WHERE Pic > 0], 'Last 30 Days' as Span
FROM Pilots

which worked fine on my machine. I don't know why it isn't working on yours.

jal
02-21-2009, 10:14 AM
Re-copy the query from post#20 and re-paste it into sql view, because it looks right to me. Just to make sure.

jal
02-21-2009, 10:16 AM
Also, try one query at a time (one of the four) to maybe isolate the one that's giving the problem.

shawnb777
02-21-2009, 10:16 AM
I needed to add the table name in front. PIC becomes Pilots.PIC and it worked!!!!!!! I need to figure out if it's giving me correct data now... but i think it is... here's a tentative THANK YOU!

jal
02-21-2009, 10:21 AM
Ok, I am getting the same error now but don't know why....

jal
02-21-2009, 10:22 AM
Glad you figure that out - it's a good thing as I never would have guessed that was the problem. I'm still scratching my head.

shawnb777
02-21-2009, 10:24 AM
This worked for me (things in bold added):

SELECT SUM(Pilots.PIC) as PIC, SUM(Pilots.Sic) as SIC, SUM(Pilots.XC) as XC, SUM(Pilots.Night) as Night, SUM(IIF(Pilots.Pic > 0, Pilots.Night, 0)) as [Night WHERE Pic > 0], 'Last 30 Days' as Span
FROM Pilots
WHERE [Date] >= Date() - 30

UNION ALL

SELECT SUM(Pilots.PIC) as PIC, SUM(Pilots.Sic) as SIC, SUM(Pilots.XC) as XC, SUM(Pilots.Night) as Night, SUM(IIF(Pilots.Pic > 0, Pilots.Night, 0)) as [Night WHERE Pic > 0], 'Last 60 Days' as Span
FROM Pilots
WHERE [Date] >= Date() - 60

UNION ALL

SELECT SUM(Pilots.PIC) as PIC, SUM(Pilots.Sic) as SIC, SUM(Pilots.XC) as XC, SUM(Pilots.Night) as Night, SUM(IIF(Pilots.Pic > 0, Pilots.Night, 0)) as [Night WHERE Pic > 0], 'Last 90 Days' as Span
FROM Pilots
WHERE [Date] >= Date() - 90

UNION ALL

SELECT SUM(Pilots.PIC) as PIC, SUM(Pilots.Sic) as SIC, SUM(Pilots.XC) as XC, SUM(Pilots.Night) as Night, SUM(IIF(Pilots.Pic > 0, Pilots.Night, 0)) as [Night WHERE Pic > 0], 'Last 120 Days' as Span
FROM Pilots
WHERE [Date] >= Date() - 120

jal
02-21-2009, 10:26 AM
What I especially don't understand is why the code in post #24 worked fine.

jal
02-21-2009, 10:27 AM
Again, it's a good thing you figured that one out, because it's still lost upon me.

shawnb777
02-21-2009, 10:30 AM
No idea, but if anyone were to know why, it wouldn't be me. Thanks for the help, I think this is all of the functionality I'll need for this application, if need extra help I'll post it up here! Thanks!