I have an Access database which is tracking hours used by each employee in each pay period.
I need a query that will allow me to look back in time and see what the total was for just the last 25 pay periods, as calculated from each of the previous 26 pay periods, for each employee. This a rolling total in which, essentially, records that are 26 pay periods (or more) older must be ignored on a per-line basis. I have five years' worth of records, and it is unfortunately necessary to retain them all, and it is very important to be able to see what the 26-pay-period running total for each employee was, together with the hours used in a particular pay period.
Basically, we're looking at 51 records total for each employee - the first pay period the query actually shows, however, is 26 pay periods ago; it has a running total based on what happened in that pay period plus the previous 25.
Tables:
HoursID, EmployeeID, PayPeriodID, HoursUsed
PayPeriodID, PayPeriodEndDate
Query Results (already working):
EmployeeID, TotalOfHoursUsedLast26PP (this query requests a date to count back from)
Query Results I Need:
EmployeeID, PayPeriodID, HoursUsed, [Total Hours Used, Based on the 25 PP immediately previous to this PP]
I've been messing around with DSum, but I can't figure out how to make it only count the last 26 PP, counting the PPs I need, for one employee at a time, for each pay period separately.
To be clear: I need to be able to look back and run this query for 26 pay periods in 2009 or something; in Excel, for one individual employee, we did something that looks like this:
Line32_HoursUsedLast26PP = Line32_HoursUsedThisPP + Line31_HoursUsedLast26PP - Line4_HoursUsedThisPP
The results are something like:
2011-5 - 338.8
2011-6 - 398.5
2011-7 - 428.7
2011-8 - 442.5
2011-9 - 451
2011-10 - 451
2011-11 - 451
2011-12 - 451
2011-13 - 451
2011-14 - 451
2011-15 - 451
2011-16 - 452.4
2011-17 - 453.1
2011-18 - 454.3
2011-19 - 454.3
2011-20 - 455
2011-21 - 456.1
2011-22 - 460.2
2011-23 - 480
2011-24 - 480
2011-25 - 480
2011-26 - 480
2012-01 - 453.2
2012-02 - 381.2
2012-03 - 301.2
2012-04 - 221.2
2012-05 - 141.2
2012-06 - 81.5
2012-07 - 51.3
2012-08 - 37.5
2012-09 - 29
2012-10 - 29
2012-11 - 29
2012-12 - 29
2012-13 - 29
2012-14 - 29
2012-15 - 29
2012-16 - 27.6
2012-17 - 26.9
2012-18 - 25.7
2012-19 - 25.7
2012-20 - 25
2012-21 - 23.9
2012-22 - 19.8
2012-23 - 0
As you can see, the running total goes up and down.
This is the actual code I have for the "find total hours in the last 26 pay periods" query; the stuff about certifications, etc., is because in any given pay period, the employees may have hours recorded under multiple certifications.
SELECT List_Employees.ID, Sum(Items_Hours_Actually_Taken.HoursActual) AS SumOfHoursActual
FROM (List_Pay_Periods INNER JOIN (List_Employees INNER JOIN (Items_Certifications INNER JOIN Items_Hours_Actually_Taken ON Items_Certifications.[CertificationID] = Items_Hours_Actually_Taken.[HoursActualCertificationID]) ON List_Employees.ID = Items_Certifications.[CertificationEmployeeID]) ON List_Pay_Periods.[PayPeriodID] = Items_Hours_Actually_Taken.[HoursActualPayPeriod]) INNER JOIN Last_26_PP_From_Today ON List_Pay_Periods.PayPeriodID = Last_26_PP_From_Today.PayPeriodID
GROUP BY List_Employees.ID;
In case it's not clear, this query depends on a separate query, called Last_26_PP_From_Today:
SELECT List_Pay_Periods.PayPeriodID, List_Pay_Periods.PPEnd
FROM List_Pay_Periods
WHERE (((List_Pay_Periods.PPEnd)<Date() And (List_Pay_Periods.PPEnd)>(Date()-14)));
I also have a query that switches to find the last 26 pay periods from any particular date:
PARAMETERS [Date] DateTime;
SELECT List_Pay_Periods.PayPeriodID, List_Pay_Periods.PPEnd
FROM List_Pay_Periods
WHERE (((List_Pay_Periods.PPEnd)<[Date] And (List_Pay_Periods.PPEnd)>([Date]-14)));
The brute-force method I thought of in desperation involved a cascading series of Make Table queries, which was when I decided perhaps someone here could offer something cleaner.
Update
Thanks to Gord, I now have everything working except that I don't see the Pay Period numbers:
SELECT hbep1.Employee, hbep1.PP
(
SELECT Sum(hbep2.Hours)
FROM Hours_By_Employee_Per_PP AS hbep2
WHERE hbep2.Employee=hbep1.Employee
AND (hbep2.PP Between hbep1.[PP]-25 And hbep1.[PP])
) AS SumLast26
FROM Hours_By_Employee_Per_PP AS hbep1;
That gets me:
Employee SumLast26
2 12
2 12
2 12
2 18
2 91
3 4
3 8
3 88
3 168
3 180
5 15
5 15
5 15
7 43
7 61
7 75
7 97
7 106
7 121
9 19
9 0