2017-06-13 49 views
0

我想保存基于几个不同列中的值的平均值,但有些行为空,因此它们需要用零替换。此外,在那个时候,我需要平均值来计入零点,以便下面的例子将平均值保存为“82.490”。所以它需要用零代替null,然后绕过平均值的任何零。从多列平均数据库值,绕过零/空

1CorrectAcc 2CorrectAcc 3CorrectAcc 4CorrectAcc 5CorrectAcc avg 
    90.345  67.890  89.234  0    0 

这是一个伪查询

UPDATE staging 
SET `avg` = (1CorrectAcc + 2CorrectAcc + 3CorrectAcc + 4CorrectAcc + 5CorrectAcc)/COUNT avoiding zeroes 
+1

这种问题是对症的设计很差。 – Strawberry

回答

1

由于值在列聚合功能不能用于

(
    coalesce(col1, 0) + 
    coalesce(col2, 0) + 
    ... 
)/(
    case when coalesce(col1, 0)=0 then 0 else 1 end + 
    case when coalesce(col2, 0)=0 then 0 else 1 end + 
    ... 
) 

如果在一行中的所有列是0或空的,一个除以0的错误将被提出,所以可以避免在where子句中添加以下条件来过滤这些行。

[where/and] not (
    coalesce(col1, 0) = 0 and 
    coalesce(col2, 0) = 0 and 
    ... 
) 
+0

对不起,我有点迷路了(我对SQL现在很不熟悉):所以,我永远不知道其中一个校正的精度是百分比还是为零,但我只需要有整体平均值在前端。所以,如果我要完成上面所有5个测试的平均值,但是想要考虑字段为空的可能性,我只会使用第一部分答案?对于如何构造它,我只是有点困惑究竟。 –

+0

第二部分是为了避免在记录可能包含0时出现错误,或者在这种情况下所有值都为null,则除数将为0 –

1

规范化架构:

DROP TABLE IF EXISTS my_table; 

CREATE TABLE my_table 
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY 
,account_id INT NOT NULL 
,value DECIMAL(7,3) 
); 

INSERT INTO my_table VALUES 
(1,1,90.345), 
(2,1,67.890), 
(3,1,89.234), 
(4,1,NULL); 

SELECT * FROM my_table; 
+----+------------+--------+ 
| id | account_id | value | 
+----+------------+--------+ 
| 1 |   1 | 90.345 | 
| 2 |   1 | 67.890 | 
| 3 |   1 | 89.234 | 
| 4 |   1 | NULL | 
+----+------------+--------+ 

SELECT account_id, ROUND(AVG(value),3) FROM my_table GROUP BY account_id; 
+------------+---------------------+ 
| account_id | ROUND(AVG(value),3) | 
+------------+---------------------+ 
|   1 |    82.490 | 
+------------+---------------------+