Mi sembra un bug e posso confermare questo comportamento sconcertante in:
10.2.14-MariaDB
Se possibile, puoi trasmettere il valore intero in un doppio:
SELECT cast(20 as double) UNION SELECT null UNION SELECT 2.2;
o assicurati di avere prima il doppio valore:
SELECT 2.2 UNION SELECT null UNION SELECT 22;
Ulteriori osservazioni dopo aver letto i commenti nella risposta di @Evan Carroll
select 20 union select null union select 2;
+------+
| 20 |
+------+
| 20 |
| NULL |
| 2 |
+------+
Ok, l'utilizzo di valori int non sembra produrre l'errore.
select 20 union select null union select 9.0;
+------+
| 20 |
+------+
| 9.9 |
| NULL |
| 9.0 |
+------+
ERRORE: sembra che l'output sia decimale (2,1)
create table tmp as select * from (select 20 as x
union
select null
union
select 9.0) as t
describe tmp;
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| x | decimal(2,1) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
L'errore non è isolato nell'interfaccia della riga di comando, esiste anche per python2-mysql-1.3.12-1.fc27.x86_64:
>>> import MySQLdb
>>> db = MySQLdb.connect(host="localhost", user="*****", passwd="*****", db="test")
>>> cur = db.cursor()
>>> cur.execute("SELECT 20 union select null union select 2.2")
3L
>>> for row in cur.fetchall() :
... print row
...
(Decimal('9.9'),)
(None,)
(Decimal('2.2'),)
Stranamente, l'errore scompare se il valore null viene spostato per primo o per ultimo:
select null union select 20 union select 9.0;
select 20 union select 9.0 union select null;
+------+
| NULL |
+------+
| NULL |
| 20.0 |
| 9.0 |
+------+
Se il valore null viene inserito per primo, il tipo risultante è decimale (20,1). Se viene inserito null l'ultimo tipo risultante è decimale (3,1)
L'errore scompare anche se viene aggiunta un'altra gamba all'unione:
select 20 union select 6 union select null union select 9.0;
+------+
| 20 |
+------+
| 20.0 |
| 6.0 |
| NULL |
| 9.0 |
+------+
risultante tipo decimale (20,1)
l'aggiunta di un altro null al centro preserva l'errore:
select 20 union select null union select null union select 9.0;
+------+
| 20 |
+------+
| 9.9 |
| NULL |
| 9.0 |
+------+
Ma l'aggiunta di un null all'inizio lo risolve:
select null union select 20 union select null union select null union select 9.0;
+------+
| NULL |
+------+
| NULL |
| 20.0 |
| 9.0 |
+------+
Come previsto, il casting del primo valore in decimale (3,1) funziona.
Infine, il cast esplicito in decimale (2,1) produce lo stesso errore ma con un avviso:
select cast(20 as decimal(2,1));
+--------------------------+
| cast(20 as decimal(2,1)) |
+--------------------------+
| 9.9 |
+--------------------------+
1 row in set, 1 warning (0.00 sec)