MS Access SQL 计算 dBµV 的对数平均值

MS Access SQL to calculate the logarithmic average of dBµV

不幸的是我的 SQL 技能很基础。我希望有一个人可以帮助我。我想计算几个 dBµV 值的对数平均值。不幸的是,我不能使用标准平均函数,因为结果不正确。

今天我有 Excel 中的数据,我的计算工作正常。不幸的是,Excel 现在已达到其性能极限,因此我已将数据导入 MS Access(我使用的是 MS Access Ver Office 365)。

我有一个 table,带有 ID、频率和 dBµV 值。我想获得特定 ID 在特定频率范围内所有 dBµV 样本的对数平均值。频率从 122 开始,最高可达 1802。并非每个 ID 都有所有频率的值。

频率范围可以如下,永远不变(意味着频率范围的开始和结束是恒定的):

在 Excel 中,我对频率范围 F122_170 使用了以下公式(B1:H1 包含 dBµV 值):

{=10*LOG(SUM(10^(B1:H1/10))/COUNTA(B1:H1))}

现在我完全迷失了 SQL 语句以获得所需的结果。

下面是我的 table“tblDev”的示例。

ID freq dBuV
3977739907 122 32.44
3977739907 130 32.24
3977739907 138 31.93
3977739907 146 30.79
3977739907 154 31.31
3977739907 162 32.39
3977739907 170 32.43
3977739907 178 32.81
3977739907 186 32.21
3977739907 194 31.23

我想要的输出如下:

ID F122_170 F178_226 F234_530 F770_up
3977739907 31.97 31.23 37.03 0.00
3845056609 32.24 23.40 41.09 38.18
3882949203 23.10 16.98 31.03 32.26
... ... ... ... ...

如果有人可以帮助我完成 SQL 声明,那就太好了。

此致帕特里克

嗯。 . .我想你可以使用:

select id,
       10 * log(avg(iif(freq between 122 and 170, 10^dBuV), null)) / log(10)
       10 * log(avg(iif(freq between 178 and 256, 10^dBuV), null)) / log(10)
from t
group by id;

注意:这会将 SUM()/COUNT() 替换为 AVG() 。 . .我认为这是同一件事。

考虑:

查询 1: Log() returns 自然对数(以 e 为底)所以要以 10 为底进行对数,将 Log(x) 除以 Log(10)

SELECT tblDev.ID, 10*(Log(Avg(10^([dBuV]/10)))/Log(10)) AS dB, 
Switch([freq]<=170,"F122_170",[freq]<=226,"F178_226",[freq]<=530,"F234_530",True,"F770_up") AS Grp
FROM tblDev
GROUP BY tblDev.ID, Switch([freq]<=170,"F122_170",[freq]<=226,"F178_226",[freq]<=530,"F234_530",True,"F770_up");

查询 2:转换查询 1 的结果

TRANSFORM First(dB)
SELECT Query1.ID
FROM Query1
GROUP BY Query1.ID
PIVOT Query1.Grp IN (F122_170,F178_226,F234_530,F770_up);

首先你需要一个Log10函数:

Public Function Log10( _
    ByVal Value As Double) _
    As Double

' Returns Log 10 of Value.
' 2015-08-17. Gustav Brock, Cactus Data ApS, CPH.

    Const Base10    As Double = 10

    ' No error handling as this should be handled
    ' outside this function.
    '
    ' Example:
    '
    '     If MyValue > 0 then
    '         LogMyValue = Log10(MyValue)
    '     Else
    '         ' Do something else ...
    '     End If
    
    Log10 = Log(Value) / Log(Base10)

End Function

然后你可以运行这个查询:

Select 
    ID, 
    Sum(AF122_170) As F122_170,
    Sum(AF178_226) As F178_226,
    Sum(AF234_530) As F234_530,
    Sum(AF770_up) As F770_up
From

    (Select 
        tblDev.ID, 
        IIf(freq Between 122 And 170, Log10(Avg(10 ^ (tblDev.dBuV / 10))) * 10, 0) As AF122_170,
        IIf(freq Between 178 And 226, Log10(Avg(10 ^ (tblDev.dBuV / 10))) * 10, 0) As AF178_226,
        IIf(freq Between 234 And 530, Log10(Avg(10 ^ (tblDev.dBuV / 10))) * 10, 0) As AF234_530,
        IIf(freq >= 770, Log10(Avg(10 ^ (tblDev.dBuV / 10))) * 10, 0) As AF770_up    From 
        tblDev
    Group By 
        ID,
        freq Between 122 And 170,
        freq Between 178 And 226,
        freq Between 234 And 530,
        freq >= 770) As T

Group By ID