使用Group By时计算Access 2007中的中位数的最佳方法

时间:2009-03-12 20:14:02

标签: sql ms-access ms-access-2007 median

我有一张表,其中包含一本书,然后是关于该书的多个价格(这是一个高度简化的样本):

ID  BOOK    PRICE
1   BOOK1   10
2   BOOK1   15
3   BOOK1   12
4   BOOK2   8
5   BOOK2   2

我很容易计算平均值,但必须有一个很好的方法来计算中位数?

当前SQL:

SELECT DISTINCTROW Books.BOOK, Avg(Books.PRICE) AS [Avg Of PRICE]
FROM Books
GROUP BY Books.BOOK;

结果:

BOOK    Avg Of PRICE
BOOK1   12.3333333333333
BOOK2   5

4 个答案:

答案 0 :(得分:3)

Jet SQL中没有中位数,除非它已经在2007年添加,但这里有一个如何获得一个的想法。你需要......

一些SQL ......

SELECT Statistics.Month, Sum(([SentTo])) AS [Sum Sent], fMedian("Statistics","Month",[Month],"SentTo") AS [Median Sent]
FROM Statistics
GROUP BY Statistics.Month;

用户定义函数(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

来自:LessThanDot Wiki

答案 1 :(得分:1)

可以使用常规查询和没有VBA在MS Access中计算中位数。中位数是第50百分位数。因此,通常创建选择查询;然后进入SQL视图并在select keyword之后包含“Top 50%”。排名上升50%;降序排名前50%。然后找到最大底部百分比结果集和最小百分比结果集。这两者的平均值是中位数。使用“前50%”时,请确保查询中的条件特定于将从中计算中位数的结果集。

答案 2 :(得分:0)

没有内置函数 - 所以你必须使用代码循环遍历记录并自己计算中位数。

使用google - 那里有很多代码示例

答案 3 :(得分:0)

我尝试使用非VBA方法,但它们都受到一定程度的限制,无法为更大的数据集提供最准确的结果。对于前50%的升序(最大值)和前50%的降序(最小值)方法,Access具有局限性,并且在按升序排序时会忽略单个值。对于四舍五入,Access使用的是银行家四舍五入,因此它并不总是根据值本身进行四舍五入,如果要四舍五入,则需要添加尾随值+ -0.00001。我还尝试了另一种没有VBA的Rank()方法,Access在对至少具有一对相同值的值进行排序时遇到了麻烦。由于上述原因,我强烈建议坚持在VBA中创建自定义功能。