Wygląda mi to na błąd i mogę potwierdzić to zagadkowe zachowanie w:
10.2.14-MariaDB
Jeśli to możliwe, możesz rzucić liczbę całkowitą na podwójną:
SELECT cast(20 as double) UNION SELECT null UNION SELECT 2.2;
lub upewnij się, że najpierw masz podwójną wartość:
SELECT 2.2 UNION SELECT null UNION SELECT 22;
Dalsze spostrzeżenia po przeczytaniu komentarzy w odpowiedzi @Evan Carroll
select 20 union select null union select 2;
+------+
| 20 |
+------+
| 20 |
| NULL |
| 2 |
+------+
Ok, użycie wartości int nie wydaje się powodować błędu.
select 20 union select null union select 9.0;
+------+
| 20 |
+------+
| 9.9 |
| NULL |
| 9.0 |
+------+
BŁĄD: Wydaje się, że dane wyjściowe są dziesiętne (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 | |
+-------+--------------+------+-----+---------+-------+
Błąd nie jest izolowany dla interfejsu wiersza poleceń, istnieje również dla 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'),)
Co dziwne, błąd znika, jeśli null zostanie przesunięty pierwszy lub ostatni:
select null union select 20 union select 9.0;
select 20 union select 9.0 union select null;
+------+
| NULL |
+------+
| NULL |
| 20.0 |
| 9.0 |
+------+
Jeśli null zostanie umieszczony jako pierwszy, wynikowy typ jest dziesiętny (20,1). Jeśli zostanie wstawiona wartość null, ostatni wynikowy typ jest dziesiętny (3,1)
Błąd znika również, jeśli do związku zostanie dodana kolejna noga:
select 20 union select 6 union select null union select 9.0;
+------+
| 20 |
+------+
| 20.0 |
| 6.0 |
| NULL |
| 9.0 |
+------+
wynikowy typ dziesiętny (20,1)
dodanie kolejnego pustego miejsca w środku zachowuje błąd:
select 20 union select null union select null union select 9.0;
+------+
| 20 |
+------+
| 9.9 |
| NULL |
| 9.0 |
+------+
Ale dodanie null na początku naprawia to:
select null union select 20 union select null union select null union select 9.0;
+------+
| NULL |
+------+
| NULL |
| 20.0 |
| 9.0 |
+------+
Zgodnie z oczekiwaniami działa rzutowanie pierwszej wartości na dziesiętną (3,1).
Wreszcie jawne rzutowanie na dziesiętne (2,1) powoduje ten sam błąd, ale z ostrzeżeniem:
select cast(20 as decimal(2,1));
+--------------------------+
| cast(20 as decimal(2,1)) |
+--------------------------+
| 9.9 |
+--------------------------+
1 row in set, 1 warning (0.00 sec)