Eu tenho esse cenário, parece que o MySQL está usando o maior valor decimal e tenta converter os outros valores para isso.
O problema é que essa consulta é gerada por uma biblioteca externa, portanto, não tenho controle sobre esse código, pelo menos nesse nível. Você tem alguma idéia de como consertar isso?
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 |
+------+
Adicionando mais contexto, estou usando o Entity Framework 6 com uma biblioteca de extensões http://entityframework-extensions.net/ para salvar alterações em lotes, especificamente o método context.BulkSaveChanges () ;, essa biblioteca cria consultas usando "select union" .
SELECT 20 UNION SELECT null UNION SELECT 40 UNION SELECT 4.3;
funciona bemRespostas:
Parece um bug para mim e posso confirmar esse comportamento intrigante em:
Se possível, você pode converter o valor inteiro em um dobro:
ou verifique se você tem o valor duplo primeiro:
Outras observações depois de ler os comentários na resposta de @Evan Carroll
Ok, o uso de valores int parece não produzir o erro.
ERRO: Parece que a saída é decimal (2,1)
O erro não está isolado na interface da linha de comandos, existe também para python2-mysql-1.3.12-1.fc27.x86_64:
Curiosamente, o erro desaparece se o nulo for movido primeiro ou por último:
Se null for colocado em primeiro lugar, o tipo resultante será decimal (20,1). Se nulo for colocado, o último tipo resultante será decimal (3,1)
O erro também desaparece se outra perna for adicionada à união:
tipo resultante decimal (20,1)
adicionar outro nulo no meio preserva o erro:
Mas adicionar um nulo no começo o corrige:
Como esperado, o lançamento do primeiro valor para decimal (3,1) funciona.
Por fim, converter explicitamente para decimal (2,1) produz o mesmo erro, mas com um aviso:
fonte
SELECT CAST(20 AS DECIMAL) AS x UNION SELECT NULL UNION SELECT 2.2;
20
as020
. O comportamento é o mesmo no MariaDB 10.2 e no MySQL 8.0 . Parece muito com o comprimento do literal afeta o tipo da coluna combinada. De qualquer forma, esse é definitivamente um bug no meu livro.Bug MDEV-15999
O bug MDEV-15999 registrado por dbdemon relatou isso. Desde então, foi corrigido no 10.3.1.
Natureza estranha do MySQL / MariaDB
Dos documentos,
Nesse caso, eles se reconciliam
decimal
einteger
promovendo o número inteiro para umdecimal
que não pode contê-lo. Eu sei que isso é horrível, mas igualmente horrível é esse comportamento silencioso assim.O que parece abrir o caminho para esse problema.
fonte
SELECT cast(20 as signed) UNION SELECT null UNION SELECT 2.2 ;
produz o mesmo resultado (9.9) errado. Mas se usarmos "unisgned", tudo correrá bem. Vai entender ...SELECT -20 UNION SELECT null UNION SELECT 2.2 ;
funciona corretamente também, como fazSELECT 20. UNION SELECT null UNION SELECT 2.2 ;
2.2
mas é muito estreito para armazenar20
. Você pode ver isso alterando a última cláusula de seleção paraCAST(2.2 AS DECIMAL(10,2))
, que é20.0
a primeira linha (implicitamente em execuçãoCAST(20 AS DECIMAL(10,2))
).2.2
. Se você tentarselect 20000 union select null union select 2.22
que você começa9999.99
, em umdecimal(6,2)
. É sempre um dígito muito curta para conter o valorNULL
valor no meio, ele calculará a precisão 1 curta.