sql - 使用 SQL 求协方差

标签 sql sql-server sql-server-2008 covariance

# dt---------indx_nm1-----indx_val1-------indx_nm2------indx_val2
2009-06-08----ABQI------1001.2------------ACNACTR----------300.05
2009-06-09----ABQI------1002.12 ----------ACNACTR----------341.19
2009-06-10----ABQI------1011.4------------ACNACTR----------382.93
2009-06-11----ABQI------1015.43 ----------ACNACTR----------362.63

我有一个看起来像 ^ 的表(但有数百行,日期从 2009 年到 2013 年)。有没有办法计算协方差: [(indx_val1 - avg(indx_val1)) * (indx_val2 - avg( indx_val2)] 除以 indx_val1indx_val2 的每个值的总行数(循环遍历整个表)并仅返回 cov( ABQIACNACTR)

最佳答案

由于您的聚合在两个不同的组上运行,因此您将需要两个不同的查询。主要的一个按 dt 分组以获取每个日期的行值。另一个查询必须在整个行集中执行 AVG()COUNT() 聚合。

要同时使用它们,您需要将它们JOIN在一起。但由于两个查询之间没有实际关系,因此它是笛卡尔积,我们将使用CROSS JOIN。实际上,它将主查询的每一行与聚合查询检索到的单行连接起来。然后,您可以使用两者中的值在 SELECT 列表中执行算术运算:

因此,基于您之前问题的查询:

SELECT 
 indxs.*,
 ((indx_val2 - indx_val2_avg) * (indx_val1 - indx_val1_avg)) / total_rows AS cv
FROM (
    SELECT 
      dt,
      MAX(CASE WHEN indx_nm = 'ABQI' THEN indx_nm ELSE NULL END) AS indx_nm1,
      MAX(CASE WHEN indx_nm = 'ABQI' THEN indx_val ELSE NULL END) AS indx_val1,
      MAX(CASE WHEN indx_nm = 'ACNACTR' THEN indx_nm ELSE NULL END) AS indx_nm2,
      MAX(CASE WHEN indx_nm = 'ACNACTR' THEN indx_val ELSE NULL END) AS indx_val2
    FROM table1 a
    GROUP BY dt
  ) indxs 
  CROSS JOIN (
    /* Join against a query returning the AVG() and COUNT() across all rows */
    SELECT
      'ABQI' AS indx_nm1_aname,
      AVG(CASE WHEN indx_nm = 'ABQI' THEN indx_val ELSE NULL END) AS indx_val1_avg,
      'ACNACTR' AS indx_nm2_aname,
      AVG(CASE WHEN indx_nm = 'ACNACTR' THEN indx_val ELSE NULL END) AS indx_val2_avg,
      COUNT(*) AS total_rows
    FROM table1 b
    WHERE indx_nm IN ('ABQI','ACNACTR')
    /* And it is a cartesian product */
  ) aggs
WHERE
  indx_nm1 IS NOT NULL
  AND indx_nm2 IS NOT NULL
ORDER BY dt

这是一个基于您之前的演示的演示:http://sqlfiddle.com/#!6/2ec65/14

关于sql - 使用 SQL 求协方差,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18019469/

相关文章:

mysql - 如何在 MySql 中测试时间相等性

c# - 遍历记录并根据条件更新数据库

sql - sql server中两个连续日期之间的差异(以天为单位)

sql-server - 将 KILL 与声明的变量一起使用

mysql - 需要在Access中查看表1中的数据,其中ID与表2中的ID匹配

sql-server - DTS 包因重复键行而终止

sql - 获取当前正在执行的存储过程的模式名称

SQL CASE语句具体例子

sql - 如何进行 SQL 查询以从表中获取某些特定范围的行

mysql - 从 MySql 移植到 SQLite 代码后,VIEW 创建不起作用