Суммируйте поле с плавающей запятой с 2 ​​цифрами в TiDB, получили число с плавающей запятой с 8 цифрами

Я перенес некоторые данные из Infobright в TiDB. Мой php-код, например:

$sql='delete from xxx where xxx';
doQuery($sql);
$sql='insert into xxx (...)';
doQuery($sql);

Я вставил 48595 записей, но их сумма является числом с плавающей запятой с 8 цифрами. Хотя поле определяется как float (10,2):

mysql> SELECT COUNT(*) FROM adpay;
+----------+
| COUNT(*) |
+----------+
|    48595 | 
+----------+
1 row in set (0.28 sec)

mysql> SELECT SUM(t.spends) FROM (SELECT spends FROM adpay LIMIT 90000) t;
+---------------+
| SUM(t.spends) |
+---------------+
|   42583533.50 | 
+---------------+
1 row in set (0.37 sec)

mysql> SELECT SUM(spends) FROM adpay;
+-------------------+
| SUM(spends)       |
+-------------------+
| 42583533.50033116 | 
+-------------------+
1 row in set (0.35 sec)

mysql> show create table adpay;
...
CREATE TABLE `adpay` (
  `date` date NOT NULL DEFAULT '0000-00-00',
  `adname` varchar(50) NOT NULL DEFAULT '',
  `country` char(10) NOT NULL DEFAULT '',
  `pf` char(20) NOT NULL DEFAULT '',
  `paydate` date NOT NULL DEFAULT '0000-00-00',
  `num` int(10) DEFAULT NULL,
  `spends` float(10,2) NOT NULL,
  `todaynum` int(11) DEFAULT '0',
  `todayspends` float(10,2) DEFAULT '0.00',
  UNIQUE KEY `sdate` (`date`,`adname`,`country`,`pf`,`paydate`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci

Итак, есть ли ошибка с TiDB, или я что-то не так делаю? Любое предложение приветствуется.


обновление:

mysql> show create table test;
+-------+------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                               |
+-------+------------------------------------------------------------------------------------------------------------+
| test  | CREATE TABLE `test` (
  `t` float(10,2) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin | 
+-------+------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)''

INSERT INTO test VALUES (1.11);
INSERT INTO test VALUES (1.111);


mysql> SELECT t,t-1.11 FROM test;
+------+----------------------------+
| t    | t-1.11                     |
+------+----------------------------+
| 1.11 | 0.000000014305114648394124 | 
| 1.11 | 0.000000014305114648394124 | 
| 1.11 | 0.000000014305114648394124 | 
+------+----------------------------+
3 rows in set (0.01 sec)

обновление 2:

Я использую просто float без указания цифр.

mysql> show create table test1;
+-------+-------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                          |
+-------+-------------------------------------------------------------------------------------------------------+
| test1 | CREATE TABLE `test1` (
  `t` float DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin | 
+-------+-------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> INSERT INTO test1 VALUES (1.11);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO test1 VALUES (1.111);
Query OK, 1 row affected (0.00 sec)

mysql> 
mysql> SELECT COUNT(*) FROM test1  WHERE t>ROUND(t, 2) ;
+----------+
| COUNT(*) |
+----------+
|        4 | 
+----------+
1 row in set (0.00 sec)

mysql> 
mysql> SELECT t,t-1.11 FROM test1;
+-------+----------------------------+
| t     | t-1.11                     |
+-------+----------------------------+
|  1.11 | 0.000000014305114648394124 | 
| 1.111 |      0.0009999418258666015 | 
|  1.11 | 0.000000014305114648394124 | 
| 1.111 |      0.0009999418258666015 | 
+-------+----------------------------+
4 rows in set (0.00 sec)

Обновление 3:

В этой таблице есть поля с разным типом, все они имеют 2 цифры.

Затем я вставляю 1.11 и 1.111 для каждого поля.

Только поле с плавающей запятой будет принимать данные как 8 цифр в TiDB:

mysql> create table test2(f float(10,2),db double(10,2), de decimal(10,2));
Query OK, 0 rows affected (1.01 sec)

mysql> insert into test2(f,db,de) values(1.11,1.11,1.11);     
Query OK, 1 row affected (0.01 sec)

mysql> insert into test2(f,db,de) values(1.111,1.111,1.111);        
Query OK, 1 row affected, 1 warning (0.01 sec)

mysql> select *,f-1.11,db-1.11,de-1.11 from test2;
+------+------+------+----------------------------+---------+---------+
| f    | db   | de   | f-1.11                     | db-1.11 | de-1.11 |
+------+------+------+----------------------------+---------+---------+
| 1.11 | 1.11 | 1.11 | 0.000000014305114648394124 |       0 |       0 | 
| 1.11 | 1.11 | 1.11 | 0.000000014305114648394124 |       0 |       0 | 
+------+------+------+----------------------------+---------+---------+
2 rows in set (0.00 sec)

Это нормально для всех трех полей в локальном mysql 5.6:

mysql> create table test2(f float(10,2),db double(10,2), de decimal(10,2));
Query OK, 0 rows affected (0.29 sec)

mysql> insert into test2(f,db,de) values(1.11,1.11,1.11);
Query OK, 1 row affected (0.06 sec)

mysql> insert into test2(f,db,de) values(1.111,1.111,1.111);
Query OK, 1 row affected, 1 warning (0.04 sec)

mysql> select *,f-1.11,db-1.11,de-1.11 from test2;
+------+------+------+--------+---------+---------+
| f    | db   | de   | f-1.11 | db-1.11 | de-1.11 |
+------+------+------+--------+---------+---------+
| 1.11 | 1.11 | 1.11 |   0.00 |    0.00 |    0.00 |
| 1.11 | 1.11 | 1.11 |   0.00 |    0.00 |    0.00 |
+------+------+------+--------+---------+---------+
2 rows in set (0.00 sec)

person chris    schedule 21.03.2018    source источник


Ответы (2)


проблема вызвана неправильным выводом типа функций sum и minus. Мы исправим это в ближайшее время. Вы можете создать задачу в https://github.com/pingcap/tidb/issues. время, если у вас возникнут проблемы при использовании TiDB. ^_^

person XHY    schedule 21.03.2018
comment
Спасибо за ваш ответ. 谢谢 - person chris; 21.03.2018

Вы можете использовать функцию ОКРУГЛ или ФОРМАТ:

SELECT ROUND(SUM(spends), 2) FROM adpay;
person Jay Shankar Gupta    schedule 21.03.2018
comment
Спасибо, ваш sql работает. Но я хочу знать, почему это происходит. - person chris; 21.03.2018
comment
Ваш sql работает правильно, но данные неверны. Я обновил информацию об этом вопросе, пожалуйста, проверьте ее. - person chris; 21.03.2018