[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

Access Query

Posted on 2016-08-21
7
Medium Priority
?
49 Views
Last Modified: 2016-08-21
I'm struggling with a query in access. I'm using the DSUM function to calculate a cumulative total for COGS that starts over each year. The issue is that I need the cumulative total to not start over each year. I'm using the design view in access to attempt the query, but have copied the sql below (as this may be most helpful for the experts).  So I need a cumulative total by Acctnbr and by Class that doesn't restart annually. Right now I can get it to a cumulative total by Acctnbr and by Class that restarts annually. I've exhausted my capabilities and am hoping for some good suggestions. Thanks.


SELECT Perpost, Year, Month, LocationCode, LocationDescription, LocationName, Class, State, LocationType, BenchmarkFacilityLocationCode, City, ZipCode, RentStartDate, RentEndDate, AcctNbr, AcctName, COGSFlag, MonthEndDate, Amount, DSum("Amount","tblUploadOccupancy(All)Flat","DatePart('m',[MonthEndDate])<=" & [Month] & " And  DatePart('yyyy', [MonthEndDate])=" & [Year] & " And [AcctNbr]=" & [AcctNbr] & " And [Class]='" & [Class] & "' ") AS CumAmount INTO tblCumulativeCOGS
FROM [tblUploadOccupancy(All)Flat]
GROUP BY Perpost, Year, Month, LocationCode, LocationDescription, LocationName, Class, State, LocationType, BenchmarkFacilityLocationCode, City, ZipCode, RentStartDate, RentEndDate, AcctNbr, AcctName, COGSFlag, MonthEndDate, Amount
HAVING (((COGSFlag)="COGS"))
ORDER BY AcctNbr;
0
Comment
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
  • Learn & ask questions
  • 3
  • 3
7 Comments
 
LVL 48

Accepted Solution

by:
Dale Fye earned 2000 total points
ID: 41764548
@bcn78,

What are you using this for?  is it a report?  Using domain functions is queries is generally considered a bad idea, unless the remainder of the query needs to be updatable.  In generally, I would write the query lik:

SELECT T1.Perpost, T1.[Year], T1.[Month], T1.LocationCode, T1.LocationDescription, T1.LocationName, T1.Class, T1.State, T1.LocationType, T1.BenchmarkFacilityLocationCode, T1.City, T1.ZipCode, T1.RentStartDate, T1.RentEndDate, T1.AcctNbr, T1.AcctName, T1.COGSFlag, T1.MonthEndDate, T1.Amount, SUM (T2.Amount) as CumAmount
FROM [tblUploadOccupancy(All)Flat] as T1
LEFT JOIN [tblUploadOccupancy(All)Flat] as T2
ON T1.[AcctNbr] = T2.[AcctNbr]
AND T1.[Class] = T2.[Class]
AND DateSerial(T1.[Year], T1.[Month] +1, 0) >= DateSerial(T2.[Year], T2.[Month] + 1, 0)
WHERE (T1.COGSFlag="COGS")
GROUP BY T1.Perpost, T1.[Year], T1.[Month], T1.LocationCode, T1.LocationDescription, T1.LocationName, T1.Class, T1.State, T1.LocationType, T1.BenchmarkFacilityLocationCode, T1.City, T1.ZipCode, T1.RentStartDate, T1.RentEndDate, T1.AcctNbr, T1.AcctName, T1.COGSFlag, T1.MonthEndDate, T1.Amount
ORDER BY T1.AcctNbr, T1.Year, T1.Month

This query uses a computed values and a non-equi-join in the join clause so it will not be editable in the query design grid.  The reason I used the computed columns on the Year and Month is that you cannot really query on those two items individually, they have to be viewed as a date, so I chose the last day of each of those months, as depicted by DateSerial([Year], [Month] + 1, 0).  Also, the non-equi join is used so that all of the records in T2 which match on account#, and class, and which have a date <= the Year/month combination in T1 are included in the query; this is what will get you the running sum.

HTH
Dale
0
 
LVL 46

Expert Comment

by:aikimark
ID: 41764555
Firstly, replace this:
HAVING (((COGSFlag)="COGS"))

Open in new window

with this
WHERE (((COGSFlag)="COGS"))

Open in new window


It might help if you posted some representative sample of the data.  I'm not sure what you mean when you write:
doesn't restart annually
0
 
LVL 48

Expert Comment

by:Dale Fye
ID: 41764561
Also note that I changed the "HAVING" clause to a "WHERE" clause.  I did this to limit the number of records that get considered in the main query.  If you have the criteria in a WHERE clause, it excludes records which don't meet the criteria before the majority of the processing.  If you put it in a HAVING clause, the query will process the SUM for all of the [COGSFlag] values and then exclude those that don't meet your final criteria from the final results.

To do this in design view, you must add a separate column in the query in the Totals row of the grid, select "WHERE" instead of "Group By"

BTW,  if you have more than one record for each AcctNbr, Class, Year, Month combination in your table, then you may need to sum the [Amount] column as well, to get the sum of [Amount] for each month.

One last thing, [Year] and [Month] are reserved word and really should not be used as field names.  You should generally give your fields meaningful names, so these might be better named like Transaction_Year and Transaction_Month, or something like that.  You should also be advised that if you persist in using these field names, you should always wrap them in brackets [ ] to prevent confusion with the functions associated with those names.

Dale
1
Veeam Task Manager for Hyper-V

Task Manager for Hyper-V provides critical information that allows you to monitor Hyper-V performance by displaying real-time views of CPU and memory at the individual VM-level, so you can quickly identify which VMs are using host resources.

 

Author Comment

by:Bcn78
ID: 41764571
Thanks Dale. I appreciate your help. Understanding your solution is little beyond my current capability, so it's very helpful for me to study and understand your response to help advance my skill set. I'm going to work with this for a while and may circle back with a question or two if you don't mind. Thanks again.

brett
0
 

Author Comment

by:Bcn78
ID: 41764572
Separately, I am using this to make a table that I can use in a subsequent query to forecast WIP and finished goods inventory
0
 

Author Closing Comment

by:Bcn78
ID: 41764574
This is great. I really appreciate it. The below was very helpful as well, it made the query run 10x faster. Thanks again Dale.

-Brett

Also note that I changed the "HAVING" clause to a "WHERE" clause.  I did this to limit the number of records that get considered in the main query.  If you have the criteria in a WHERE clause, it excludes records which don't meet the criteria before the majority of the processing.  If you put it in a HAVING clause, the query will process the SUM for all of the [COGSFlag] values and then exclude those that don't meet your final criteria from the final results.
0
 
LVL 48

Expert Comment

by:Dale Fye
ID: 41764582
glad to help, Brett.

non-equi JOINs can be confusing, but can generally be re-written as a WHERE clause as below:

SELECT T1.Perpost, T1.[Year], T1.[Month], T1.LocationCode, T1.LocationDescription, T1.LocationName, T1.Class, T1.State, T1.LocationType, T1.BenchmarkFacilityLocationCode, T1.City, T1.ZipCode, T1.RentStartDate, T1.RentEndDate, T1.AcctNbr, T1.AcctName, T1.COGSFlag, T1.MonthEndDate, T1.Amount, SUM (T2.Amount) as CumAmount
FROM [tblUploadOccupancy(All)Flat] as T1
INNER JOIN [tblUploadOccupancy(All)Flat] as T2
ON T1.[AcctNbr] = T2.[AcctNbr]
AND T1.[Class] = T2.[Class]
WHERE (T1.COGSFlag="COGS")
AND (DateSerial(T1.[Year], T1.[Month] +1, 0) >= DateSerial(T2.[Year], T2.[Month] + 1, 0))
GROUP BY T1.Perpost, T1.[Year], T1.[Month], T1.LocationCode, T1.LocationDescription, T1.LocationName, T1.Class, T1.State, T1.LocationType, T1.BenchmarkFacilityLocationCode, T1.City, T1.ZipCode, T1.RentStartDate, T1.RentEndDate, T1.AcctNbr, T1.AcctName, T1.COGSFlag, T1.MonthEndDate, T1.Amount
ORDER BY T1.AcctNbr, T1.Year, T1.Month

In this version, which you could edit in the query design grid, I've simply moved the non-equi JOIN and moved that clause into the WHERE clause.  Consider a simple example of a table (tblItemSales) with sales for a single item and fields (ItemID, SalesDate, Quantity) and just a couple of records:

ItemID      SalesDate   Quantity
1                 7/1/16           100
1                 7/2/16           150
1                 7/3/16           125

if you create a query:

SELECT T1.ItemID, T1.SalesDate, T1.Quantity, T2.SalesDate, T2.Quantity
FROM tblItemSales as T1
INNER JOIN tblItemSales as T2 ON T1.ItemID = T2.ItemID

you would get 9 records (three records from T2 for each record in T1).

If you added a WHERE clause to only include the record from T2 which are <= T1.Sales date then you would initially get 9 records in the recordset, but the WHERE clause would filter out three, leaving 6 records (1 from T2 for T1.SalesDate = 7/1/16, 2 records from T2 for T1.SalesDate = 7/2/16, and 3 records from T2 for T1.SalesDate = 7/3/16).

Theoretically, if you move that WHERE clause into a non-equi JOIN, you would only get the 6 records initially.  So, the non-equi JOIN would get reduce the number of records to be processed.

Hope this helps.

Dale
1

Featured Post

Fill in the form and get your FREE NFR key NOW!

Veeam® is happy to provide a FREE NFR server license to certified engineers, trainers, and bloggers.  It allows for the non‑production use of Veeam Agent for Microsoft Windows. This license is valid for five workstations and two servers.

Question has a verified solution.

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

Preparing an email is something we should all take special care with – especially when the email is for somebody you may not know very well. The pressures of everyday working life stacked with a hectic office environment can make this a real challen…
If you need a simple but flexible process for maintaining an audit trail of who created, edited, or deleted data from a table, or multiple tables, and you can do all of your work from within a form, this simple Audit Log will work for you.
In Microsoft Access, when working with VBA, learn some techniques for writing readable and easily maintained code.
Have you created a query with information for a calendar? ... and then, abra-cadabra, the calendar is done?! I am going to show you how to make that happen. Visualize your data!  ... really see it To use the code to create a calendar from a q…

649 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