Solved

Moving-average for nested tables in Access 2013

Posted on 2016-09-25
7
22 Views
Last Modified: 2016-10-01
Hello,

I have a table which resembles the following:

-------------------------------------------
ItemID  |  BuyDate |     Cost
-------------------------------------------
1       | 1/1/2014 |    $25.00
2       | 1/1/2014 |    $29.40
3       | 1/1/2014 |    $50.80
4       | 2/1/2014 |    $16.70
5       | 3/1/2014 |    $48.50
6       | 3/1/2014 |    $34.70
.
.

Open in new window


I intend to calculate the 5-day moving average for the above data. My SQL code in Access 2013 resembles the following:

SELECT B1.BuyDate AS Buy_Date, SUM(B1.Costs) AS Total_Costs, (
        SELECT Avg(B2.CostSum)
        FROM 
                (SELECT U3.BuyDate as BDate, SUM(B3.Cost) as CostSum
                 FROM Bought AS B3
                 GROUP BY B3.BuyDate) AS B2
        WHERE
        B2.BDate BETWEEN DateAdd("d", -4, B1.BuyDate) AND B2.BDate
        GROUP BY B2.BDate
 ) AS [5-day_MovAvg]
FROM Bought AS B1
GROUP BY B1.BuyDate;

Open in new window


However, when I tried to run the code, a prompt popped-up in Access, stating that at most only one record can be returned.

Please advise on how I may be able to do this. My desired SQL output would be as follows:

--------------------------------------------------------
Buy_Date |Total_Costs| 5-day_MovAvg
--------------------------------------------------------
1/1/2014 |   $105.20 |  $105.20
2/1/2014 |    $16.70 |  $60.95
3/1/2014 |    $83.20 |  $68.37
.
.
.

Open in new window


Thanks.
0
Comment
Question by:sz14
  • 3
  • 2
  • 2
7 Comments
 
LVL 49

Assisted Solution

by:Gustav Brock
Gustav Brock earned 250 total points
ID: 41815433
Perhaps this will do:
SELECT 
    B1.BuyDate AS Buy_Date, 
    SUM(B1.Costs) AS Total_Costs, 
        (SELECT Avg(CostSum)
        FROM 
            (SELECT SUM(B3.Costs) AS CostSum
            FROM Bought AS B3
            GROUP BY B3.BuyDate
            HAVING B3.BuyDate BETWEEN DateAdd("d", -4, B1.BuyDate) AND B1.BuyDate)) AS
    [5-day_MovAvg]
FROM 
    Bought AS B1
GROUP BY 
    B1.BuyDate;

Open in new window

/gustav
0
 
LVL 19

Assisted Solution

by:crystal (strive4peace) - Microsoft MVP, Access
crystal (strive4peace) - Microsoft MVP, Access earned 250 total points
ID: 41815435
try something like this:
SELECT B1.BuyDate AS Buy_Date, SUM(B1.Costs) AS Total_Costs,
   (
      SELECT Avg(b2.Costs)
      FROM Bought AS B2
      WHERE
         B2.BuyDate BETWEEN DateAdd("d", -4, B1.BuyDate ) AND B1.BuyDate
   ) AS [MovAvg5Day]
FROM Bought AS B1
GROUP BY B1.BuyDate;
0
 

Author Comment

by:sz14
ID: 41815821
Hi Gustav & Crystal,

Firstly, thank you very much for your prompt replies to my query. :)

Gustav, I have attempted to run your solution in Access 2013, but a prompt appears when I attempt to run this query, requesting for a parameter value to be entered for B1.BuyDate. This is strange as Access usually prompts the user for this input if the variable was not defined prior to execution of the SQL code, so Access prompts the user for a value to be entered at run-time.

Crystal, I have also tried to run your code in Access 2013. It seems that the MovAvg values are obtained by averaging the values for the day. So, for instance, the total costs for 1/1/2014 is $105.20, but the moving average was calculated to be $35.20 (which is incorrect, as it should be averaging the total sums on a daily basis, and not for individual entries in the table). Please see the attached screenshots for what happens when the code is run in Access 2013.

Please advise.

Thanks.

(P.S. BTW, there are a couple of typos in my question posted above:
1. The header for the third field of the table should read Costs, and not Cost.
2. In my code, it should read SELECT B3.BuyDate, and not U3.BuyDate.

I sincerely apologize for the typos. )
Crystal.JPG
Gustav.JPG
0
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 
LVL 49

Expert Comment

by:Gustav Brock
ID: 41815828
Try with the alias Buy_Date:

    HAVING B3.BuyDate BETWEEN DateAdd("d", -4, B1.Buy_Date) AND B1.Buy_Date)) AS

/gustav
0
 

Accepted Solution

by:
sz14 earned 0 total points
ID: 41815836
Hi Gustav & Crystal,

I have modified the code so that it now gives the correct moving average on a daily basis.

The code is as shown below (for future reference by anyone who intends to do this using SQL in Access):

SELECT B1.BuyDate AS Buy_Date, SUM(B1.Costs) AS Total_Costs, (
       SELECT Avg(B2.Total_Cost)
       FROM 
(SELECT B3.BuyDate AS Buy_Date, SUM(B3.Costs) AS Total_Cost
FROM Bought as B3
GROUP BY B3.BuyDate) AS B2
       WHERE
          B2.Buy_Date BETWEEN DateAdd("d", -4, B1.BuyDate ) AND B1.BuyDate 
    ) AS MovAvg5Day
FROM Bought AS B1
GROUP BY B1.BuyDate;

Open in new window


Thanks for your time & response to the query.

:)
0
 
LVL 19
ID: 41816438
thanks for sharing your solution -- glad you got it
0
 

Author Closing Comment

by:sz14
ID: 41824649
The final solution which I provided solves the problem, but kudos to Gustav & Crystal who have provided a nudge in the right direction (through their code).
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

When you are entering numbers in a speadsheet, and don't remember what 6×7 is, you just type “=6*7" instead. It works in every cell! This is not so in Access. To enter the elusive 42 in a text box, you have to find a calculator, and then copy the re…
QuickBooks® has a great invoice interface that we were happy with for a while but that changed in 2001 through no fault of Intuit®. Our industry's unit names are dictated by RUS: the Rural Utilities Services division of USDA. Contracts contain un…
Familiarize people with the process of retrieving data from SQL Server using an Access pass-thru query. Microsoft Access is a very powerful client/server development tool. One of the ways that you can retrieve data from a SQL Server is by using a pa…
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 …

760 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

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now