Ich habe dieses Szenario, es sieht so aus, als würde MySQL den größten Dezimalwert annehmen und versuchen, die anderen Werte in diesen umzuwandeln.
Das Problem ist, dass diese Abfrage von einer externen Bibliothek generiert wird, sodass ich zumindest auf dieser Ebene keine Kontrolle über diesen Code habe. Haben Sie eine Idee, wie Sie das beheben können?
SELECT 20 AS x
UNION SELECT null
UNION SELECT 2.2;
+------+
| x |
+------+
| 9.9 | -- why from 20 to 9.9
| NULL |
| 2.2 |
+------+
erwartetes Ergebnis
+------+
| x |
+------+
| 20 | -- or 20.0, doesn't matter really in my case
| NULL |
| 2.2 |
+------+
Wenn ich mehr Kontext hinzufüge , verwende ich Entity Framework 6 mit einer Erweiterungsbibliothek http://entityframework-extensions.net/ , um Änderungen in Stapeln zu speichern, insbesondere die Methode context.BulkSaveChanges (). Diese Bibliothek erstellt Abfragen mit "select union". .
SELECT 20 UNION SELECT null UNION SELECT 40 UNION SELECT 4.3;
funktioniert gutAntworten:
Sieht für mich wie ein Fehler aus und ich kann dieses rätselhafte Verhalten bestätigen in:
Wenn möglich, können Sie den ganzzahligen Wert in ein Double umwandeln:
oder stellen Sie sicher, dass Sie zuerst den doppelten Wert haben:
Weitere Beobachtungen nach dem Lesen der Kommentare in der Antwort von @Evan Carroll
Ok, die Verwendung von int-Werten scheint den Fehler nicht zu erzeugen.
FEHLER: Die Ausgabe scheint dezimal zu sein (2,1).
Der Fehler ist nicht auf die Befehlszeilenschnittstelle beschränkt, sondern existiert auch für python2-mysql-1.3.12-1.fc27.x86_64:
Seltsamerweise verschwindet der Fehler, wenn null zuerst oder zuletzt verschoben wird:
Wenn null an erster Stelle steht, ist der resultierende Typ dezimal (20,1). Wenn null gesetzt wird, ist der letzte resultierende Typ dezimal (3,1).
Der Fehler verschwindet auch, wenn der Vereinigung ein weiteres Bein hinzugefügt wird:
resultierende Typ Dezimalzahl (20,1)
Durch Hinzufügen einer weiteren Null in der Mitte bleibt der Fehler erhalten:
Das Hinzufügen einer Null am Anfang behebt das Problem:
Wie erwartet funktioniert das Umwandeln des ersten Werts in eine Dezimalzahl (3,1).
Schließlich führt das explizite Umwandeln in eine Dezimalzahl (2,1) denselben Fehler aus, jedoch mit einer Warnung:
quelle
SELECT CAST(20 AS DECIMAL) AS x UNION SELECT NULL UNION SELECT 2.2;
20
als angeben020
. Das Verhalten ist in MariaDB 10.2 und in MySQL 8.0 dasselbe . Es sieht sehr nach der Länge des Literal aus, die sich auf den Typ der kombinierten Spalte auswirkt. Auf jeden Fall ist dies definitiv ein Fehler in meinem Buch.Fehler MDEV-15999
Bug MDEV-15999 durch eingereicht dbdemon berichtet dies. Es wurde seitdem in 10.3.1 behoben.
Seltsame MySQL / MariaDB-Natur
Aus den Dokumenten,
In diesem Fall versöhnen sie sich
decimal
undinteger
fördern die Ganzzahl zu einer Zahl,decimal
die sie nicht enthalten kann. Ich weiß, dass das schrecklich ist, aber genauso schrecklich ist, dass sich das so still verhält.Das scheint den Weg für dieses Problem zu ebnen.
quelle
SELECT cast(20 as signed) UNION SELECT null UNION SELECT 2.2 ;
erzeugt das gleiche (9.9) falsche Ergebnis. Aber wenn wir dort "unisgned" verwenden, geht alles gut. Go figure ...SELECT -20 UNION SELECT null UNION SELECT 2.2 ;
funktioniert auch richtig, genauso wieSELECT 20. UNION SELECT null UNION SELECT 2.2 ;
2.2
aber zu eng ist , um ihn zu halten20
. Sie können dies sehen, indem Sie die letzte Auswahlklausel in ändernCAST(2.2 AS DECIMAL(10,2))
, die20.0
als erste Zeile angegeben wird (implizit ausgeführtCAST(20 AS DECIMAL(10,2))
).2.2
. Wenn Sie versuchenselect 20000 union select null union select 2.22
, bekommen Sie9999.99
in einemdecimal(6,2)
. Es ist immer eine Ziffer zu kurz, um den Wert zu haltenNULL
Wert in die Mitte eingeben, wird die Genauigkeit 1 kurz berechnet.