我试图找到一种更快的方法来计算Access中的中位数。您可以在下面的代码中看到该代码,它一次查询一个商品代码,进行排序,然后计算中位数。有时有600个商品代码,这些商品每个都有1000多个基础。例如,我正在使用的特定表总共有150,000条记录,并且运行速度非常慢。有没有一种更好的方法可以一次计算每个记录的中位数,而不是一次计算一个项目代码。
Function FIncPercentile(ByVal posCode As Single, ByVal k As Single, ByVal tbl As String) As Variant
Dim rstRec As Recordset
Dim db As Database
Dim n As Integer
Dim i As Single
Dim res, d1, d2 As Currency
' Create recordset from query
Set db = CurrentDb
Set rstRec = db.OpenRecordset("SELECT Co, Base " & _
"FROM " & tbl & " " & _
"WHERE Code = " & pos & " " & _
"ORDER BY Base ASC;")
' Skip if there are no matches
If IsNull(rstRec!base) Or rstRec.RecordCount = 0 Then
FBasePercentile = Null
Exit Function
End If
' Count records
rstRec.MoveLast
n = rstRec.RecordCount
rstRec.MoveFirst
' Calculate the index where k is the percentile
i = n * k
' Test the decimal and find value accordingly
If i = Int(i) Then
rstRec.Move i - 1
d1 = rstRec!base
rstRec.MoveNext
d2 = rstRec!base
FIncPercentile = (d1 + d2) / 2
Else
i = Round(i + 0.5, 0)
rstRec.Move i - 1
FIncPercentile = rstRec!base
End If
End Function
Access中没有中值功能。Excel有一个,但我相信它限制为30个数字,因此,即使您想尝试使用自动化功能,我也不认为它适用于您的情况。
我认为通过微调功能并让Microsoft的Jet Engine预编译查询,您可能会看到明显的速度提高。
在所有这些更改之前和之后进行计时,看看是否有明显的区别
我更正了一些错别字,这些错别字可能不是错别字-我假设CODE是一个长整数-这又一次可能是我错了。同样,我的更改以“ ***************”开头
创建预编译参数查询
创建名为“ qdfPrepMedian ”的新查询
复制/粘贴SQL >> PARAMETERS [What Code] Long; SELECT Co, Base FROM <YourTableName> WHERE Code = [What Code] ORDER BY Base ASC;
保存查询
调整功能
Option Explicit
'***********************
' changed posCode to Long
'***********************
Function FIncPercentile(ByVal posCode As Long, ByVal k As Single, ByVal tbl As String) As Variant
'***********************
' CREATE/USE Precompiled Parameter Query
' Create New Query called "qdfPrepMedian"
' Copy/Paste SQL >> PARAMETERS [What Code] Long; SELECT Co, Base FROM <YourTableName> WHERE Code = [What Code] ORDER BY Base ASC;
Const QRY_BY_CODES As String = "qdfPrepMedian"
Dim qdf As QueryDef
'
'***********************
Dim rstRec As Recordset
Dim db As Database
Dim n As Integer
Dim i As Single
' Declare all Currency variables on separate lines
' Otherwise they will be variants
Dim res As Currency
Dim d1 As Currency
Dim d2 As Currency
Set db = CurrentDb
'***********************
' Create readonly recordset from querydef
Set qdf = db.QueryDefs(QRY_BY_CODES)
qdf.Parameters("What Code") = posCode ' matches LONG variable passed to function
Set rstRec = qdf.OpenRecordset(dbOpenSnapshot, dbReadOnly) ' Readonly is sometimes faster
'***********************
' Use WITH rstRec
With rstRec
' Skip if there are no matches
If IsNull(!base) Or .RecordCount = 0 Then
'*** Is this a type ***
' FBasePercentile = Null
' Should it BE
FIncPercentile = Null
Exit Function
End If
' Count records
.MoveLast
n = .RecordCount
.MoveFirst
' Calculate the index where k is the percentile
i = n * k
' Test the decimal and find value accordingly
If i = Int(i) Then
.Move i - 1
d1 = !base
.MoveNext
d2 = !base
FIncPercentile = (d1 + d2) / 2
Else
i = Round(i + 0.5, 0)
.Move i - 1
FIncPercentile = !base
End If
End With
End Function
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句