Tengo este escenario, parece que MySQL está tomando el valor decimal más grande e intenta convertir los otros valores a eso.
El problema es que esta consulta es generada por una biblioteca externa, por lo que no tengo control sobre este código, al menos en este nivel. ¿Tienes alguna idea de cómo solucionar esto?
SELECT 20 AS x
UNION SELECT null
UNION SELECT 2.2;
+------+
| x |
+------+
| 9.9 | -- why from 20 to 9.9
| NULL |
| 2.2 |
+------+
Resultado Esperado
+------+
| x |
+------+
| 20 | -- or 20.0, doesn't matter really in my case
| NULL |
| 2.2 |
+------+
Agregando más contexto, estoy usando Entity Framework 6 con una biblioteca de extensión http://entityframework-extensions.net/ para guardar los cambios en lotes, específicamente el método context.BulkSaveChanges () ;, esta biblioteca crea consultas usando "select union" .
SELECT 20 UNION SELECT null UNION SELECT 40 UNION SELECT 4.3;
funciona bienRespuestas:
A mí me parece un error y puedo confirmar este comportamiento desconcertante en:
Si es posible, puede convertir el valor entero a un doble:
o asegúrese de tener el valor doble primero:
Observaciones adicionales después de leer los comentarios en la respuesta de @Evan Carroll
Ok, el uso de valores int no parece producir el error.
ERROR: Parece que la salida es decimal (2,1)
El error no está aislado de la interfaz de línea de comando, también existe para python2-mysql-1.3.12-1.fc27.x86_64:
Por extraño que parezca, el error desaparece si nulo se mueve primero o último:
Si se coloca nulo primero, el tipo resultante es decimal (20,1). Si se coloca nulo, el último tipo resultante es decimal (3,1)
El error también desaparece si se agrega otro tramo a la unión:
tipo resultante decimal (20,1)
agregar otro nulo en el medio conserva el error:
Pero agregar un valor nulo al principio lo corrige:
Como se esperaba, el primer valor de conversión a decimal (3,1) funciona.
Finalmente, la conversión explícita a decimal (2,1) produce el mismo error pero con una advertencia:
fuente
SELECT CAST(20 AS DECIMAL) AS x UNION SELECT NULL UNION SELECT 2.2;
20
como020
. El comportamiento es el mismo en MariaDB 10.2 y en MySQL 8.0 . Parece que la longitud del literal afecta el tipo de columna combinada. En cualquier caso, este es definitivamente un error en mi libro.Error MDEV-15999
El error MDEV-15999 presentado por dbdemon informó esto. Desde entonces se ha solucionado en 10.3.1.
Naturaleza extraña de MySQL / MariaDB
De los documentos,
En este caso, se reconcilian
decimal
yinteger
promueven el número entero a undecimal
que no puede contenerlo. Sé que es horrible, pero igualmente horrible es este comportamiento silencioso de esa manera.Lo que parece allanar el camino para este problema.
fuente
SELECT cast(20 as signed) UNION SELECT null UNION SELECT 2.2 ;
produce el mismo (9.9) resultado incorrecto. Pero si usamos "sin diseñar" allí todo va bien. Go figure ...SELECT -20 UNION SELECT null UNION SELECT 2.2 ;
funciona correctamente también, como lo haceSELECT 20. UNION SELECT null UNION SELECT 2.2 ;
2.2
pero es demasiado estrecho para mantener20
. Puede ver esto cambiando la última cláusula select aCAST(2.2 AS DECIMAL(10,2))
, que aparece20.0
como la primera fila (en ejecución implícitaCAST(20 AS DECIMAL(10,2))
).2.2
. Si lo intentasselect 20000 union select null union select 2.22
, obtienes9999.99
, en adecimal(6,2)
. Siempre es un dígito demasiado corto para mantener el valorNULL
valor en el medio, calcula la precisión 1 corta.