Reputation: 8302
I have a table which contains a book and then multiple prices about the book (this is a highly simplified sample):
ID BOOK PRICE 1 BOOK1 10 2 BOOK1 15 3 BOOK1 12 4 BOOK2 8 5 BOOK2 2
I am easily calculating the average, but there must be a nice way to calculate the median?
Current SQL:
SELECT DISTINCTROW Books.BOOK, Avg(Books.PRICE) AS [Avg Of PRICE]
FROM Books
GROUP BY Books.BOOK;
Results:
BOOK Avg Of PRICE BOOK1 12.3333333333333 BOOK2 5
Upvotes: 4
Views: 22483
Reputation: 1
I've tried to use non-VBA methods and they are all somewhat limited and not being able to give you the most accurate result for a bigger data set. For the Top 50 Percent Asc (Max) and Top 50 Percent Desc (Min) method, Access has a limitation and it omits single values when ordered in ascending order. For rounding, Access is using bankers rounding so it's not always rounding up depending on the value itself, you need to add a trailing value of +-0.00001 if you want to round up or down. I also tried another Rank()method without VBA and Access is having trouble ranking values that has at least one pair of identical values. For reasons above, I strongly suggest sticking to creating customize function in VBA.
Upvotes: 0
Reputation: 19
Median can be be calculated in MS Access using just regular queries and without VBA. Median is the 50th percentile. So, create select queries normally; then go into SQL view and include "Top 50 Percent" after select keyword. Sort ascending for bottom 50 percent; sort descending for top 50 percent. Then find maximum of bottom percent result set and minimum of top percent result set. The average of these two is the median. When using "Top 50 Percent", make sure criteria in the query is specific for that result set from which median will be calculated.
Upvotes: 1
Reputation: 91356
There is no Median in Jet SQL, unless it has been added for 2007, but here is an idea of how to get one. You will need ...
Some SQL ...
SELECT Statistics.Month, Sum(([SentTo])) AS [Sum Sent], fMedian("Statistics","Month",[Month],"SentTo") AS [Median Sent]
FROM Statistics
GROUP BY Statistics.Month;
And a User Defined Function (UDF).
Function fMedian(SQLOrTable, GroupFieldName, GroupFieldValue, MedianFieldName)
Dim rs As DAO.Recordset
Set db = CurrentDb
Set rs1 = db.OpenRecordset(SQLOrTable, dbOpenDynaset)
If IsDate(GroupFieldValue) Then
GroupFieldValue = "#" & GroupFieldValue & "#"
ElseIf Not IsNumeric(GroupFieldValue) Then
GroupFieldValue = "'" & Replace(GroupFieldValue, "'", "''") & "'"
End If
rs1.Filter = GroupFieldName & "=" & GroupFieldValue
rs1.Sort = MedianFieldName
Set rs = rs1.OpenRecordset()
rs.Move (rs.RecordCount / 2)
If rs.RecordCount Mod 2 = 0 Then
varMedian1 = rs.Fields(MedianFieldName)
rs.MoveNext
fMedian = (varMedian1 + rs.Fields(MedianFieldName)) / 2
Else
fMedian = rs.Fields(MedianFieldName)
End If
End Function
From: LessThanDot Wiki
Upvotes: 5