gpt4 book ai didi

postgresql - Postgres regr_slope 返回 NULL

转载 作者:行者123 更新时间:2023-11-29 14:14:17 24 4
gpt4 key购买 nike

有人可以帮我理解 regr_slope 在数据集中有行的情况下返回 NULL 的情况吗?例如:

log=> select * from sb1 order by id, ts;
id | elapsed | ts
------+---------+----------------
317e | 86 | 1552861322.627
317e | 58 | 1552861324.747
317e | 52 | 1552861325.722
317e | 58 | 1552861326.647
317e | 82 | 1552861327.609
317e | 118 | 1552861328.514
317e | 58 | 1552861329.336
317e | 58 | 1552861330.317
317e | 54 | 1552861330.935
3441 | 68 | 1552861324.765
3441 | 84 | 1552861326.665
3441 | 56 | 1552861327.627
3441 | 50 | 1552861330.952
5fe6 | 42 | 1552993248.398
5fe6 | 44 | 1552993255.883
5fe6 | 44 | 1553166049.261
c742 | 62 | 1552861322.149
c742 | 68 | 1552861322.455
(18 rows)

log=> select id, regr_slope(elapsed, ts) as trend from sb1 group by id;
id | trend
------+----------------------
c742 |
317e |
5fe6 | 5.78750952760444e-06
3441 |
(4 rows)

有趣的是,相同的数据集和函数在 Oracle 11.2 中返回不同的结果:

SQL> select * from sb1 order by id, ts;

ID ELAPSED TS
---------- ---------- ----------------
317e 86 1552861322.627
317e 58 1552861324.747
317e 52 1552861325.722
317e 58 1552861326.647
317e 82 1552861327.609
317e 118 1552861328.514
317e 58 1552861329.336
317e 58 1552861330.317
317e 54 1552861330.935
3441 68 1552861324.765
3441 84 1552861326.665
3441 56 1552861327.627
3441 50 1552861330.952
5fe6 42 1552993248.398
5fe6 44 1552993255.883
5fe6 44 1553166049.261
c742 62 1552861322.149
c742 68 1552861322.455

18 rows selected.

SQL> select id, regr_slope(elapsed, ts) from sb1 group by id;

ID REGR_SLOPE(ELAPSED,TS)
---------- ----------------------
c742 19.6078431
5fe6 5.7875E-06
317e -1.0838511
3441 -3.8283951

虽然 5fe6 的结果相同,但我不知道这是否意味着 Postgres 和 Oracle 都存在问题,或者两者都存在问题。

最佳答案

深入研究代码后,我有了答案:

问题在于,在这种情况下,直到 v12 的 PostgreSQL 的幼稚方法会导致不必要的大舍入误差。

让我们考虑 id = 'c742':

regr_slope 的公式如下:

regr_slope := (N ⋅ Σ(Xi⋅< em>Yi) - ΣXi ⋅ Σ Yi)/(N ⋅ Σ(Xi2) - ΣXi ⋅ ΣX )

问题出在除数上:

SELECT 2::float8 * (1552861322.149::float8 * 1552861322.149::float8 +
1552861322.455::float8 * 1552861322.455::float8) -
(1552861322.149::float8 + 1552861322.455::float8) *
(1552861322.149::float8 + 1552861322.455::float8);

?column?
----------
-2048
(1 row)

由于结果为负,PostgreSQL 返回 NULL 结果。

如果使用精确计算(使用 numeric),这不会发生:

SELECT 2 * (1552861322.149 * 1552861322.149 +
1552861322.455 * 1552861322.455) -
(1552861322.149 + 1552861322.455) *
(1552861322.149 + 1552861322.455);

?column?
----------
0.093636
(1 row)

自从 PostgreSQL 提交 e954a727f0c8872bf5203186ad0f5312f6183746 ,事情有所改进,在 PostgreSQL v12 中,PostgreSQL 也返回了正确的结果:

select id, regr_slope(elapsed, ts) from sb1 group by id;

id | regr_slope
------+-----------------------
c742 | 19.607858781290517
317e | -1.0838511987808963
5fe6 | 5.787509483586743e-06
3441 | -3.828395463097356
(4 rows)

关于postgresql - Postgres regr_slope 返回 NULL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55291084/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com