在 TiDB 中对一个 2 位浮点数字段求和,得到 8 位浮点数
Sum a float field with 2 digits in TiDB, got float with 8 digits
我从 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:
我只使用浮点数,没有指定数字。
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:
这个table有不同类型的字段,都是2位数。
然后我为每个字段插入 1.11 和 1.111。
在 TiDB 中只有 float 字段会将数据取为 8 位:
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)
本地3个字段都可以 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)
您可以使用 ROUND 或 FORMAT 函数:
SELECT ROUND(SUM(spends), 2) FROM adpay;
问题是由函数 sum
和 minus
的类型推断不正确引起的。我们会尽快修复它。
下次使用 TiDB 遇到问题可以在 https://github.com/pingcap/tidb/issues 中创建 issue。 ^_^
我从 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:
我只使用浮点数,没有指定数字。
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:
这个table有不同类型的字段,都是2位数。
然后我为每个字段插入 1.11 和 1.111。
在 TiDB 中只有 float 字段会将数据取为 8 位:
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)
本地3个字段都可以 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)
您可以使用 ROUND 或 FORMAT 函数:
SELECT ROUND(SUM(spends), 2) FROM adpay;
问题是由函数 sum
和 minus
的类型推断不正确引起的。我们会尽快修复它。
下次使用 TiDB 遇到问题可以在 https://github.com/pingcap/tidb/issues 中创建 issue。 ^_^