2017-06-13 3 views
0

Ich versuche, einen Durchschnitt basierend auf den Werten in mehreren verschiedenen Spalten zu speichern, aber einige Zeilen sind Null, so dass sie durch Null ersetzt werden müssen. Auch an diesem Punkt muss der Durchschnitt die Nullen berücksichtigen, so dass das Beispiel unten den Mittelwert als "82.490" speichern würde. Daher muss NULL durch Null ersetzt werden und dann alle Nullen für den Durchschnitt umgehen.Durchschnitt der Datenbankwerte aus mehreren Spalten, Umgehung Nullen/null

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

Dies ist eine pseudo-Abfrage

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

Diese Art von Problem ist symptomatisch für schlechtes Design. – Strawberry

Antwort

1

Wie die Werte in Spalte Aggregationsfunktion sind, können nicht

(
    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 + 
    ... 
) 

Wenn alle Spalten 0 oder null in einer Reihe verwendet werden, Es wird eine Division durch Fehler 0 ausgelöst. Es kann vermieden werden, folgende Bedingung in where-Klausel einzufügen, um diese Zeilen zu filtern.

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

Entschuldigung, ich bin dort ein wenig verloren (ich bin mit SQL derzeit sehr wenig vertraut): Also weiß ich nie, ob eine der korrigierten Genauigkeiten ein Prozentsatz oder Null ist, aber ich muss nur den Gesamtdurchschnitt haben am vorderen Ende. Wenn ich also einen Durchschnitt aller 5 obigen Tests erstellen würde, aber die Möglichkeit, dass ein Feld null ist, berücksichtigen möchte, würde ich nur den ersten Teil Ihrer Antwort verwenden - ich bin nur ein wenig verwirrt, wie ich es strukturieren könnte genau. –

+0

Der zweite Teil besteht darin, Fehler zu vermeiden, wenn ein Datensatz 0 oder null für alle Werte enthalten kann. In diesem Fall ist der Divisor 0 –

1

Normalisieren Ihr Schema:

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 | 
+------------+---------------------+ 
Verwandte Themen