Trông giống như một lỗi với tôi và tôi có thể xác nhận hành vi khó hiểu này trong:
10.2.14-MariaDB
Nếu có thể, bạn có thể truyền giá trị số nguyên thành gấp đôi:
SELECT cast(20 as double) UNION SELECT null UNION SELECT 2.2;
hoặc đảm bảo bạn có giá trị gấp đôi trước:
SELECT 2.2 UNION SELECT null UNION SELECT 22;
Quan sát thêm sau khi đọc các bình luận trong câu trả lời của @Evan Carroll
select 20 union select null union select 2;
+------+
| 20 |
+------+
| 20 |
| NULL |
| 2 |
+------+
Ok, sử dụng giá trị int dường như không tạo ra lỗi.
select 20 union select null union select 9.0;
+------+
| 20 |
+------+
| 9.9 |
| NULL |
| 9.0 |
+------+
LRI: Có vẻ như đầu ra là số thập phân (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ỗi không bị cô lập với giao diện dòng lệnh, nó cũng tồn tại cho 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'),)
Điều kỳ lạ là lỗi sẽ biến mất nếu null được di chuyển trước hoặc cuối:
select null union select 20 union select 9.0;
select 20 union select 9.0 union select null;
+------+
| NULL |
+------+
| NULL |
| 20.0 |
| 9.0 |
+------+
Nếu null được đặt đầu tiên, loại kết quả là thập phân (20,1). Nếu null được đặt loại kết quả cuối cùng là số thập phân (3,1)
Lỗi cũng biến mất nếu một chân khác được thêm vào liên minh:
select 20 union select 6 union select null union select 9.0;
+------+
| 20 |
+------+
| 20.0 |
| 6.0 |
| NULL |
| 9.0 |
+------+
kết quả kiểu thập phân (20,1)
thêm một null khác ở giữa sẽ bảo vệ lỗi:
select 20 union select null union select null union select 9.0;
+------+
| 20 |
+------+
| 9.9 |
| NULL |
| 9.0 |
+------+
Nhưng việc thêm null vào lúc đầu sẽ sửa nó:
select null union select 20 union select null union select null union select 9.0;
+------+
| NULL |
+------+
| NULL |
| 20.0 |
| 9.0 |
+------+
Như dự kiến đúc giá trị đầu tiên thành thập phân (3,1) hoạt động.
Cuối cùng, chuyển rõ ràng sang thập phân (2.1) tạo ra cùng một lỗi nhưng với một cảnh báo:
select cast(20 as decimal(2,1));
+--------------------------+
| cast(20 as decimal(2,1)) |
+--------------------------+
| 9.9 |
+--------------------------+
1 row in set, 1 warning (0.00 sec)