CORR函数严格按皮尔逊公式r=cov(X,Y)/(σₓ×σᵧ)计算,非平均或拟合;主流数据库均原生支持但行为有异:Oracle支持窗口、MySQL原生不支持、PostgreSQL要求double精度、Hive/MaxCompute对NULL整行过滤且不兼容非数值类型。

SQL 中的 CORR 函数能直接算出皮尔逊相关系数,不是因为它“聪明”,而是它底层硬编码实现了标准统计公式——你不用手写协方差除以标准差乘积,数据库引擎替你做了。
为什么 CORR 不是简单平均或拟合,而是严格按皮尔逊定义计算
CORR 对应的是 Pearson 相关系数的数学定义:r = cov(X,Y) / (σₓ × σᵧ),即两列的协方差除以各自标准差的乘积。所有主流数据库(Oracle、PostgreSQL、MaxCompute、Hive)的 CORR 都默认走这条路,不依赖近似或抽样。
- Oracle 和 PostgreSQL 的
CORR(expr1, expr2)在聚合模式下,等价于先算COVAR_POP(expr1, expr2),再除以STDDEV_POP(expr1) * STDDEV_POP(expr2) - MaxCompute 的
corr(col1, col2)明确文档写明“皮尔逊相关系数”,且对NULL行自动跳过,和公式要求一致 - 它不接受非数值类型——遇到
VARCHAR或DATE会报错,因为公式只对数字有意义
CORR 在不同 SQL 引擎中的参数行为差异
表面写法一样,但实际处理逻辑有关键区别,容易导致结果不一致:
- Oracle 支持
OVER()窗口用法,比如CORR(x,y) OVER (PARTITION BY category),而 MySQL 原生不支持CORR函数(5.7 及以前无此函数,8.0+ 仍需自定义或变量模拟) - PostgreSQL 的
corr()要求输入为double precision,如果传integer会隐式转,但若存在大量整数溢出风险(如大整数相乘),可能影响精度 - MaxCompute 的
corr()允许两列类型不同(INT和DOUBLE混用),但 Oracle 会尝试隐式转换,失败则报ORA-00932 - 所有实现都忽略含
NULL的整行——不是填充 0,也不是跳过单个值,而是整条记录出局
常见错误现象和排查点
返回 #DIV/0!、NULL 或意外的 0,往往不是数据问题,而是被忽略的前提条件触发了:
-
CORR返回NULL:某列全为相同值(标准差为 0),或两列有效行数不一致(比如一列有 10 行非空,另一列只有 9 行) - Oracle 报
ORA-00932: inconsistent datatypes:传了DATE或字符串列,即使内容全是数字也不行,必须显式TO_NUMBER() - Hive/Spark SQL 中
CORR结果为NaN:输入列存在Infinity或-Infinity,而这些值在聚合时未被过滤 - 和 Excel 的
CORREL()结果不一致:Excel 默认忽略文本和逻辑值,但把"0"字符串当 0 处理;SQL 引擎一律不认字符串,必须提前清洗
真正要注意的,不是“怎么调用”,而是“哪些行实际参与了计算”——CORR 的静默过滤机制(跳 NULL、跳非数字、跳标准差为 0 的组)比函数本身更影响结果可信度。

















