计算sqlite中的方差

时间:2014-09-17 16:34:53

标签: sql sqlite aggregate variance

我想计算表格列的方差。 例如。计算方差的公式包含聚合 和标量函数是:

(SUM((var-AVG(var))*(var-AVG(var))))/(COUNT(var)-1)

其中var是用于计算方差的变量列。

在Sqlite中使用此功能的最佳方法是什么,如:

SELECT (SUM((var-AVG(var))*(var-AVG(var))))/(COUNT(var)-1) AS Variance FROM
TableX

3 个答案:

答案 0 :(得分:3)

AVG(var)的值将在每个要求和的表达式中使用,因此您必须使用子查询单独计算它:

SELECT SUM((var-(SELECT AVG(var) FROM TableX))*
           (var-(SELECT AVG(var) FROM TableX)) ) / (COUNT(var)-1) AS Variance
FROM TableX

答案 1 :(得分:0)

在对上述CL答案的部分回答中,我不确定SELECT AVG(var)FROM TableX是否被缓存或计算两次(因为它出现两次)。对于大型表/视图,这可能会成为一个问题。您可能想要另一种选择: -

SELECT diff_squared / [n-1] FROM
(
    SELECT diff * diff AS diff_squared FROM 
    (
        SELECT x - mean AS diff FROM 
        (
            SELECT [Var] AS x FROM TableX
        ) innerData
        LEFT JOIN
        (
            SELECT avg(x) AS mean FROM
            (
                SELECT [Var] AS x FROM TableX
            ) 
        ) stats
    ) outerData
) LEFT JOIN
(
    SELECT count(x) - 1 AS [n-1] FROM 
    (
        SELECT [Var] AS x FROM TableX
    )   
) nMinus1

答案 2 :(得分:0)

我需要计算 5 分钟的平均值,并想以相同的 5 分钟间隔计算方差。

简而言之:

  1. 创建 5 分钟平均值的视图
  2. 尽管我不同意 COUNT()-1 中的 -1,但在此线程中使用此视图来计算方差,就像上面的 CL 一样。

也许不是很优雅,但对我来说更容易捕捉。我用 LibreOffice Calc(VAR.P 函数)检查了结果。

数据

数据位于名为 magic 的表中。

CREATE TABLE magic(
  "dt" TEXT,
  "qccm" REAL,
  PRIMARY KEY (dt)
);

创建 5 分钟平均值的视图

CREATE VIEW v_magic5m(
"dt",
"qccm",
)
AS SELECT
datetime(round(cast(strftime('%s',dt) AS INT)/300)*300, 'unixepoch') AS rndtime,
avg(qccm),
GROUP BY rndtime;

计算方差

WITH tmp
AS (
    SELECT
    datetime(round(cast(strftime('%s',dt) AS INT)/300)*300, 'unixepoch') AS rnd_dt, 
    qccm
    FROM magic
)
SELECT
    tmp.rnd_dt,
    v_magic5m.qccm AS avg_qccm,
    SUM( (tmp.qccm - v_magic5m.qccm)*(tmp.qccm - v_magic5m.qccm) ) / COUNT(tmp.qccm) AS var_qccm
FROM tmp
LEFT JOIN v_magic5m ON tmp.rnd_dt=v_magic5m.dt
GROUP BY tmp.rnd_dt;

输出如下所示:

rnd_dt               avg_qccm          var_qccm        
-------------------  ----------------  ----------------
2021-04-28 09:55:00  334.292929292929  765.924293439445
2021-04-28 10:00:00  332.743333333333  571.924122222222
2021-04-28 10:05:00  333.04            501.165066666667