我在MS Access 2013中有以下查询,而不是返回中值。
字段IU始终为NULL(空白)或1.列GM是在-5和5之间格式化0.0000的数字,偶尔会有NULL值。
SELECT IU, DMedian("GM","tblFirst250","IU=1") AS MedianByIU
FROM tblFirst250
WHERE IU = 1
GROUP BY IU;
但是,在尝试调试时,当我使用DAvg而不是DMedian时,我得到一个平均值。
我得到了DMedian(因为我知道Access 2013没有它)来自: https://msdn.microsoft.com/en-us/library/dd789431(v=office.12).aspx
以下是我在名为basDMedian的模块中的代码,作为我数据库的一部分:
Public Function DMedian( _
ByVal strField As String, ByVal strDomain As String, _
Optional ByVal strCriteria As String) As Variant
' Purpose:
' To calculate the median value
' for a field in a table or query.
' In:
' strField: the field.
' strDomain: the table or query.
' strCriteria: an optional WHERE clause to
' apply to the table or query.
' Out:
' Return value: the median, if successful;
' Otherwise, an Error value.
Dim db As DAO.Database
Dim rstDomain As DAO.Recordset
Dim strSQL As String
Dim varMedian As Variant
Dim intFieldType As Integer
Dim intRecords As Integer
Const errAppTypeError = 3169
On Error GoTo HandleErr
Set db = CurrentDb()
' Initialize return value.
varMedian = Null
' Build SQL string for recordset.
strSQL = "SELECT " & strField & " FROM " & strDomain
' Only use a WHERE clause if one is passed in.
If Len(strCriteria) > 0 Then
strSQL = strSQL & " WHERE " & strCriteria
End If
strSQL = strSQL & " ORDER BY " & strField
Set rstDomain = db.OpenRecordset(strSQL, dbOpenSnapshot)
' Check the data type of the median field.
intFieldType = rstDomain.Fields(strField).Type
Select Case intFieldType
Case dbByte, dbInteger, dbLong, _
dbCurrency, dbSingle, dbDouble, dbDate
' Numeric field.
If Not rstDomain.EOF Then
rstDomain.MoveLast
intRecords = rstDomain.RecordCount
' Start from the first record.
rstDomain.MoveFirst
If (intRecords Mod 2) = 0 Then
' Even number of records.
' No middle record, so move to the
' record right before the middle.
rstDomain.Move ((intRecords \ 2) - 1)
varMedian = rstDomain.Fields(strField)
' Now move to the next record, the
' one right after the middle.
rstDomain.MoveNext
' And average the two values.
varMedian = _
(varMedian + rstDomain.Fields(strField)) / 2
' Make sure you return a date, even when
' averaging two dates.
If intFieldType = dbDate And Not IsNull(varMedian) Then
varMedian = CDate(varMedian)
End If
Else
' Odd number or records.
' Move to the middle record and return its value.
rstDomain.Move ((intRecords \ 2))
varMedian = rstDomain.Fields(strField)
End If
Else
' No records; return Null.
varMedian = Null
End If
Case Else
' Non-numeric field; so raise an app error.
Err.Raise errAppTypeError
End Select
DMedian = varMedian
ExitHere:
On Error Resume Next
rstDomain.Close
Set rstDomain = Nothing
Exit Function
HandleErr:
' Return an error value.
DMedian = CVErr(Err.Number)
Resume ExitHere
End Function
我的目标是获取IU = 1的记录的GM列的中值。我得到的值是NULL /空白。如果有更好的方法,请告诉我。谢谢!
答案 0 :(得分:2)
要求您的pArray
表达式忽略 GM 字段中的任何空值。
DMedian
基本上发生的事情是SELECT IU, DMedian("GM","tblFirst250","IU=1 AND GM Is Not Null") AS MedianByIU
FROM tblFirst250
WHERE IU = 1
GROUP BY IU;
打开一个按 GM 排序的记录集,然后(大致)在记录集的一半处移动以获得中值。但如果该行中的值碰巧是空的......
DMedian
... GM
--
Null
Null <- median
2
告诉你中位数是空的。因此,指示DMedian
仅加载DMedian
为您提供非空值的中位数的行。