Query for average of the last 10 records

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • charli
    New Member
    • Nov 2008
    • 23

    Query for average of the last 10 records

    I have a table of Waste IDs, with a relationship with a second table of Waste Weights:
    WasteIDs
    Code:
    id  name
    1. Paper
    2. Cardboard
    3. Cans
    WasteWeights:
    Code:
    Id   date   kg
    1. 1/1/09 12
    1. 1/2/09  24
    2. 1/1/09  2
    I want to look up the last 10 wasteweights for an id, and get an average.
    So I can do:
    Code:
    SELECT avg(weight)
    FROM (SELECT TOP 10 weight
          FROM wasteweights
          WHERE id=1
          ORDER BY [date] DESC)
    to get the last 10, but this only works when i put in particular IDs, I want the average of the top 10 for each ID so I can have it as part of a report
    so the final datasheet will be like:
    Code:
    Id   Avg
    1. 18
    2.  2
    Any ideas? Could it be done with multiple queries maybe?
    Last edited by NeoPa; Jun 23 '09, 01:51 PM. Reason: Please use the [CODE] tags provided.
  • NeoPa
    Recognized Expert Moderator MVP
    • Oct 2006
    • 32634

    #2
    I think you'll need multiple queries I'm afraid.

    Comment

    • NeoPa
      Recognized Expert Moderator MVP
      • Oct 2006
      • 32634

      #3
      No guarantees, but this may work :
      Code:
      SELECT   [ID]
           ,   (SELECT Avg([Weight])
                FROM (SELECT TOP 10
                               [Weight]
                      FROM     [WasteWeights] AS Inner
                      WHERE    Inner.ID=Outer.ID
                      ORDER BY Inner.Date DESC)) AS AvgWeight
      FROM     [WasteWeights] AS Outer
      GROUP BY [ID]

      Comment

      • charli
        New Member
        • Nov 2008
        • 23

        #4
        Hmm, I get a 'syntax error in FROM clause', and it highlights the later one but even if you attempt putting the innermost query in, you get the same error

        It doesn't like the placement of 'As' or using keywords Inner and Outer, but even once those are altered (which could be breaking its intended use horribly, sorry):

        Code:
        SELECT [streamid], (SELECT Avg([Weight]) as avg  FROM 
        (SELECT TOP 10  [Weight] as inn  FROM  [WasteWeights]  WHERE  Inn.streamid=Out.streamID ORDER BY Inn.Date DESC)
        AS AvgWeight) AS Out
        FROM WasteWeights
        GROUP BY [streamID];
        I get the 'streamid is no included in an aggregate function' error
        Last edited by charli; Jun 23 '09, 03:15 PM. Reason: actually my idea didn't work, oops

        Comment

        • NeoPa
          Recognized Expert Moderator MVP
          • Oct 2006
          • 32634

          #5
          If it doesn't work then it doesn't.

          I don't have any live data to test on so just knocked something up. I wouldn't really expect it to work in Access (it may in SQL Server or other such full-featured SQL server).

          I'm afraid your proposed solution will not return correct data even if it were to run. It's not asking the right question.

          I think you need to return to the idea of multiple queries for this.

          Comment

          • charli
            New Member
            • Nov 2008
            • 23

            #6
            Thank you for your help! I think I give up now, and I'll just settle on the overall average, rather than the average fo the last X records, its a bit too much for my poor brain to handle!

            Thanks,
            Charli

            Comment

            • NeoPa
              Recognized Expert Moderator MVP
              • Oct 2006
              • 32634

              #7
              It's certainly not straightforward Charli.

              The TOP Predicate is rarely ever usable outside of the main, outer query in my experience. Unless a specific grouping is selected of course. Where it would require running more than once to make sense (as in this case) it will always be hard if even possible.

              Comment

              • charli
                New Member
                • Nov 2008
                • 23

                #8
                How I ended up doing this, incase anyone has the same problem:

                Query 1 (called top10): SELECT TOP 10 streamid FROM table WHERE streamid=[Reports]![Confirm]![streamid] ORDER by [date] DESC;
                -- returns the top 10 most recent records for an id

                Query 2 (called Avgtop10): SELECT AVG(top10) FROM top10 WHERE streamid = [Reports]![Confirm]![streamid];
                -- returns the average of the top 10 most recent records for an id

                Then put Query Avgtop10 into a report (removing all the headers)
                Made a second report (called Confirm) with a list of streamids (just SELECT streamid FROM table), embed the Avgtop10 report as a sub report.

                This is a very long and convoluted way to get a list of IDs, and the average of the 10 most recent records for each id!

                Comment

                • NeoPa
                  Recognized Expert Moderator MVP
                  • Oct 2006
                  • 32634

                  #9
                  I'm not sure it is Charli.

                  It's convoluted yes, but then the requirement is convoluted. This seems to be a sensible solution to the problem. No more complex than you would reasonably expect for such a problem (in my view at least).

                  Congratulation for the solution by the way.

                  Comment

                  Working...