Solved

Microsoft Access Query - SQL Help For Cumulative Sum

Posted on 2016-07-15
97 Views
Hi,
Apologies as I am an accountant by trade, but am trying to sharpen my access/sql skills to build out better forecasting/planning capabilities for my company.

I currently have a table with the below fields:

MonthEndDate: Monthly end dates for each month 2016 - 2018
Year: The corresponding Year in "yyyy" format for each of the month end dates
Month: The corresponding Month in "m" format for each of the month end dates
Employee ID: unique identifier for ~200 employees
MonthlySalary: The amount of monthly salary paid to each of the employees, for each month

For tax purposes, I'm trying to calculate the cumulative salary for each employee, each year (I need the cumulative amounts per employee to start over each year in January). I've spent a solid 5-6 hours trying to solve this on my own using DSUM as well as trying to write a SQL query in access that inner joins the table called "tblMonthlySalary" to itself and sums the field MonthlySalary.

I'm not even getting close to getting this worked out, so figured I would ask the experts for some guidance.

Thanks!

Brett
0
Question by:Bcn78
[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
• 6
• 5
• 3
• +2

LVL 120

Expert Comment

ID: 41712727
try this query

select  [Employee ID], sum([MonthlySalary]), [Year]
from tblMonthlySalary
group by [Employee ID],[Year]

post back if this is good enough for you
0

Author Comment

ID: 41712839
Thanks Rey,

This works for an annual total, but I need the cumulative totals by month. For example, if an employee makes \$120K per year. I need the cumulative total in June to be \$60K. When I add "monthenddate" to the query above the sum([monthlysalary]) AS CumulativeTotal just returns the monthly amount for each month (it does not cumulatively sum the prior months). For example, monthenddate 6/30/2017 returns \$10K instead of \$60K.

Any thoughts on how to make this happen?

Thanks.

Brett
0

LVL 40

Expert Comment

ID: 41712901
Do you like to see all months with cumulative salary or only one, which can be selected on some form?
0

LVL 37

Expert Comment

ID: 41712905
This is simple and straight forward to do in a report because a report is a linear process and so it this.  Queries are set operations and so you have to work to make this happen.

In a report, add a control in the appropriate section bound to the salary field and set it's RunningSum Property (on the Data tab) to Over Group.  If the detail section contains one row for each month, the first salary column will show the salary for that month, the second one - with the RunningSum property will show the running sum.

If you do this in a query, you need to use a query that joins the salary table to itself using a non-equi join.

Select a.Employee, a.PayDate, a.Salary, Sum(b.Salary) as RunningSum
From tblEmployee  Left Join tblEmployee as b On a.Employee = b.Employee AND a.PayDate >= b.PayDate
Where a.PayYear = Forms!yourform!SelectYear and b.PayYear = Forms!yourform!SelectYear
Group by a.Employee, a.PayDate, a.Salary
1

Author Comment

ID: 41712907
@als315 - all months
0

LVL 120

Expert Comment

ID: 41712925
try this

SELECT tblMonthlySalary.[Employee ID], tblMonthlySalary.Year, tblMonthlySalary.Month, tblMonthlySalary.MonthlySalary, DSum("MonthlySalary","tblMonthlySalary","DatePart('m',[MonthEndDate])<=" & [Month] & " And  DatePart('yyyy', [MonthEndDate])<=" & [Year] & " And [Employee ID]=" & [Employee ID]) AS CumSalary
FROM tblMonthlySalary
GROUP BY tblMonthlySalary.[Employee ID], tblMonthlySalary.Year, tblMonthlySalary.Month, tblMonthlySalary.MonthlySalary;
0

LVL 120

Expert Comment

ID: 41712941
include a sorting by year

SELECT tblMonthlySalary.[Employee ID], tblMonthlySalary.Year, tblMonthlySalary.Month, tblMonthlySalary.MonthlySalary, DSum("MonthlySalary","tblMonthlySalary","DatePart('m',[MonthEndDate])<=" & [Month] & " And  DatePart('yyyy', [MonthEndDate])<=" & [Year] & " And [Employee ID]=" & [Employee ID]) AS CumSalary
FROM tblMonthlySalary
GROUP BY tblMonthlySalary.[Employee ID], tblMonthlySalary.Year, tblMonthlySalary.Month, tblMonthlySalary.MonthlySalary
ORDER BY tblMonthlySalary.Year;

to filter by year

SELECT tblMonthlySalary.[Employee ID], tblMonthlySalary.Year, tblMonthlySalary.Month, tblMonthlySalary.MonthlySalary, DSum("MonthlySalary","tblMonthlySalary","DatePart('m',[MonthEndDate])<=" & [Month] & " And  DatePart('yyyy', [MonthEndDate])<=" & [Year] & " And [Employee ID]=" & [Employee ID]) AS CumSalary
FROM tblMonthlySalary
GROUP BY tblMonthlySalary.[Employee ID], tblMonthlySalary.Year, tblMonthlySalary.Month, tblMonthlySalary.MonthlySalary
HAVING (((tblMonthlySalary.Year)=[Enter Year]))
ORDER BY tblMonthlySalary.Year;
0

LVL 40

Assisted Solution

als315 earned 250 total points
ID: 41712942
Look at sample. I've changed names in table form Year to Tyear and Month to Tmonth, because it not good idea to use reserved words in column names.
Query:
``````SELECT tblMonthlySalary.[Employee ID], tblMonthlySalary.MonthEndDate, tblMonthlySalary.TYear AS Y, tblMonthlySalary.TMonth AS M, tblMonthlySalary.MonthlySalary, DSum("[MonthlySalary]","tblMonthlySalary","[Employee ID] = " & [Employee ID] & " and TYear = " & [TYear] & " and TMonth <= " & [TMonth]) AS CumSalary
FROM tblMonthlySalary;
``````
DBSalary.accdb
1

LVL 120

Expert Comment

ID: 41712950
typo error correction

SELECT tblMonthlySalary.[Employee ID], tblMonthlySalary.Year, tblMonthlySalary.Month, tblMonthlySalary.MonthlySalary, DSum("MonthlySalary","tblMonthlySalary","DatePart('m',[MonthEndDate])<=" & [Month] & " And  DatePart('yyyy', [MonthEndDate]) =" & [Year] & " And [Employee ID]=" & [Employee ID]) AS CumSalary
FROM tblMonthlySalary
GROUP BY tblMonthlySalary.[Employee ID], tblMonthlySalary.Year, tblMonthlySalary.Month, tblMonthlySalary.MonthlySalary
HAVING (((tblMonthlySalary.Year)=[Enter Year]))
ORDER BY tblMonthlySalary.Year;
0

LVL 22

Expert Comment

ID: 41712984
I guess your query should be like this
``````SELECT [Employee ID], (MonthlySalary*[Month]) AS ProgressiveSalary, MonthEndDate
FROM tblMonthlySalary
Group BY [Employee ID],MonthEndDate,[Month],[Year],(MonthlySalary*[Month])
Order By [Employee ID],MonthEndDate
``````
0

Author Comment

ID: 41713097
@Rey and @ALS. The cumulative calculation is showing #Error because of what appears to be a data type mismatch. I tried to trouble shoot this by running an update query to update [Month] to be month([MonthEndDate]) and year to be year([MonthEndDate]) in both short text and number formats. Neither of these seemed to resolve the issue however.

EmployeeNumber (not Employee ID; my apologies) is in short text format because our open requisitions contain alpha numeric codes (eg: R1).

MonthlySalary is in number format

I've tried the below queries for each of your solutions but seem to be running into the same issue (#Error):

Rey:
SELECT tblMonthlySalary.EmployeeNumber, tblMonthlySalary.Year, tblMonthlySalary.Month, tblMonthlySalary.MonthlySalary, DSum("MonthlySalary","tblMonthlySalary","DatePart('m',[MonthEndDate])<=" & [Month] & " And  DatePart('yyyy', [MonthEndDate])<=" & [Year] & " And EmployeeNumber=" & EmployeeNumber) AS CumSalary
FROM tblMonthlySalary
GROUP BY tblMonthlySalary.EmployeeNumber, tblMonthlySalary.Year, tblMonthlySalary.Month, tblMonthlySalary.MonthlySalary;

ALS:
SELECT tblMonthlySalary.EmployeeNumber, tblMonthlySalary.MonthEndDate, tblMonthlySalary.Year, tblMonthlySalary.Month, tblMonthlySalary.MonthlySalary, DSum("MonthlySalary","tblMonthlySalary","EmployeeNumber = " & EmployeeNumber & " and Year = " & Year & " and Month <= " & Month) AS CumSalary
FROM tblMonthlySalary;

Any thoughts would be much appreciated. Thanks for all your help. Apologies again.

brett
0

LVL 22

Expert Comment

ID: 41713113
As your table already contains fields with the year and month values why are you using the datepart function?
If you look at the query posted above by me there you have simply to add a WHERE criteria.

You have a monthly salary value and the month and year value, so you have simply to muultiply your monthly salary for the month value to know the progressive salary at that month, all grouped year by year...
0

LVL 120

Accepted Solution

Rey Obrero (Capricorn1) earned 250 total points
ID: 41713125
@brett

fields Month, Year and EmployeeNumber should be "NUMBER" data type.

SELECT tblMonthlySalary.[EmployeeNumber], tblMonthlySalary.Year, tblMonthlySalary.Month, tblMonthlySalary.MonthlySalary, DSum("MonthlySalary","tblMonthlySalary","DatePart('m',[MonthEndDate])<=" & [Month] & " And  DatePart('yyyy', [MonthEndDate])=" & [Year] & " And [EmployeeNumber]=" & [EmployeeNumber]) AS CumSalary
FROM tblMonthlySalary
GROUP BY tblMonthlySalary.[EmployeeNumber], tblMonthlySalary.Year, tblMonthlySalary.Month, tblMonthlySalary.MonthlySalary
ORDER BY tblMonthlySalary.Year;
0

LVL 120

Expert Comment

ID: 41713143
@Ferruccio Accalai,
your query will work if the salary will remain fix through out the year.
0

LVL 22

Expert Comment

ID: 41713155
@Rey
Well, looking at the inputs I didn't see any request about salary changes during the same year but thinking about it yes, your right
0

Author Comment

ID: 41713163
@ Rey. Thank you!. This worked. I obviously never could have solved this on my own. I'm trying to understand why EmployeeNumber needs to be Number format and cannot be text?

Thanks again.
0

Author Closing Comment

ID: 41713165
Thank you!!
0

Featured Post

Question has a verified solution.

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

Suggested Solutions

Phishing attempts can come in all forms, shapes and sizes. No matter how familiar you think you are with them, always remember to take extra precaution when opening an email with attachments or links.
In Part II of this series, I will discuss how to identify all open instances of Excel and enumerate the workbooks, spreadsheets, and named ranges within each of those instances.
In Microsoft Access, learn how to use Dlookup and other domain aggregate functions and one method of specifying a string value within a string. Specify the first argument, which is the expression to be returned: Specify the second argument, which â€¦
With Microsoft Access, learn how to start a database in different ways and produce different start-up actions allowing you to use a single database to perform multiple tasks. Specify a start-up form through options: Specify an Autoexec macro: Usâ€¦
Suggested Courses
Course of the Month4 days, 1 hour left to enroll