AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 9187
Accepted
Bryan Agee
Bryan Agee
Asked: 2011-12-15 15:28:54 +0800 CST2011-12-15 15:28:54 +0800 CST 2011-12-15 15:28:54 +0800 CST

MySQL 从 float (10,2) 到 fixed(10,2) 的转换

  • 772

我有一个数据库,其中包含存储为浮点数的财务数据。自然地,这可能会在随机时间出现一个真正的问题(例如,当存在无法用浮点算法足够接近地近似的精确值时)。

我的问题是:

  • 当您选择字段时,使用会 ALTER TABLE table MODIFY field fixed(10,2)保留 MySQL 当前显示的固定值吗?
  • 该值是否有可能是其他的东西?
mysql floating-point
  • 3 3 个回答
  • 19063 Views

3 个回答

  • Voted
  1. Best Answer
    RolandoMySQLDBA
    2011-12-15T15:51:28+08:002011-12-15T15:51:28+08:00

    坏消息:我不认为价值会被保留!

    我写了这篇文章(2011 年 7 月 25 日),展示了浮点数对转换的敏感程度。

    好消息:这是您可以安全地比较数据转换的方法:

    如果你的桌子有这些特点

    • 表被称为moneytable
    • 您要转换的字段称为moneyfield
    • 主键被称为moneyid

    然后运行这些命令:

    DROP TABLE IF EXISTS moneytabletest;
    CREATE TABLE moneytabletest LIKE moneytable;
    ALTER TABLE moneytabletest MODIFY moneyfield fixed(10,2);
    INSERT INTO moneytabletest SELECT * FROM moneytable;
    SELECT A.moneyid,A.moneyfield olddata,B.moneyfield newdata
    FROM moneytable A LEFT JOIN moneytabletest B USING (moneyid)
    WHERE A.moneyfield <> B.moneyfield;
    

    这是底线: 如果查询返回任何行,LEFT JOIN则转换将是错误的。您将不得不修改 的定义moneyfield,重新加载moneytabletest表,并LEFT JOIN一次又一次地运行查询,直到查询没有返回任何行LEFT JOIN。一旦返回零 (0) 行,您就会知道哪种转换是安全的。

    试试看 !!!

    • 7
  2. Bryan Agee
    2011-12-16T07:58:03+08:002011-12-16T07:58:03+08:00

    根据 Rolando 的回答,我想出了一个更简单的方法来进行分阶段转换,然后进行比较。在有问题的表中,我首先添加了一个相同类型的新字段。我镜像了这些值,运行了转换,并比较了结果值。例如,因为Amount float(10,2) NOT NULL我用过:

    ALTER TABLE `table` ADD `AmountStaged` float(10,2) NOT NULL;
    UPDATE `table` SET `AmountStaged` = `Amount`;
    ALTER TABLE `table` MODIFY `AmountStaged` decimal(10,2) NOT NULL;
    SELECT * FROM `table` WHERE round(`Amount`,2) <> `AmountStaged`;
    

    令人惊讶的是,有几个表(一些超过 30k 行),只有一个值不匹配。幸运的是,该特定记录上设置了已删除标志,因此无论如何它都无关紧要。因此,在获得有利的结果后,最后一步是两个命令:

    ALTER TABLE `table` DROP `Amount`;
    ALTER TABLE `table` CHANGE `AmountStaged` `Amount` decimal(10,2) NOT NULL;
    

    编辑:零停机时间的替代方法是删除AmountStaged列并转换Amount列,因为转换应该与我们运行测试的转换相同。

    ALTER TABLE `table` MODIFY `Amount` decimal(10,2) NOT NULL;
    ALTER TABLE `table` DROP `AmountStaged`;
    
    • 4
  3. derkien
    2014-10-13T23:05:24+08:002014-10-13T23:05:24+08:00

    感谢以上所有答案!

    我总共有超过 130、972 行,其中有几个浮点列,其中包含类似货币的数据。所以今天我需要将这些列转换为十进制,因为我们在精度方面遇到了一些问题。我使用了上述解决方案之一,但结果并不完全符合我的需要,正如作者所说:

    您将不得不修改 moneyfield 的定义,重新加载 moneytabletest 表,并一次又一次地运行 LEFT JOIN 查询,直到 LEFT JOIN 查询没有返回任何行。一旦返回零 (0) 行,您就会知道哪种转换是安全的。

    另一个很幸运,差异记录被标记为已删除......在我的情况下,在此操作之后:

    ALTER TABLE `target_table` ADD `dummy_price` decimal(20,2) NOT NULL;
    UPDATE `target_table` SET `dummy_price` = CAST(`float_price` as DECIMAL(20,2));
    SELECT `float_price`, `dummy_price`  FROM `target_table` WHERE round(`float_price`, 2) <> `dummy_price`;
    

    ...我有 87 行,不匹配。所以我决定像这样更新它:

    UPDATE `target_table` 
    SET `dummy_price` = round(`float_price`, 2) 
    WHERE round( `float_price` , 2 ) <> `dummy_price`
    

    好吧,在那之后我得到了我需要的一切。float_price从eq 到 的所有四舍五入的数据dummy_price,我认为已经足够了。

    我想我会帮助某人。

    • 0

相关问题

  • 是否有任何 MySQL 基准测试工具?[关闭]

  • 我在哪里可以找到mysql慢日志?

  • 如何优化大型数据库的 mysqldump?

  • 什么时候是使用 MariaDB 而不是 MySQL 的合适时机,为什么?

  • 组如何跟踪数据库架构更改?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    您如何显示在 Oracle 数据库上执行的 SQL?

    • 2 个回答
  • Marko Smith

    如何选择每组的第一行?

    • 6 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    我可以查看在 SQL Server 数据库上运行的历史查询吗?

    • 6 个回答
  • Marko Smith

    如何在 PostgreSQL 中使用 currval() 来获取最后插入的 id?

    • 10 个回答
  • Marko Smith

    如何在 Mac OS X 上运行 psql?

    • 11 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Marko Smith

    将数组参数传递给存储过程

    • 12 个回答
  • Martin Hope
    Manuel Leduc PostgreSQL 多列唯一约束和 NULL 值 2011-12-28 01:10:21 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Stuart Blackler 什么时候应该将主键声明为非聚集的? 2011-11-11 13:31:59 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    BrunoLM Guid vs INT - 哪个更好作为主键? 2011-01-05 23:46:34 +0800 CST
  • Martin Hope
    bernd_k 什么时候应该使用唯一约束而不是唯一索引? 2011-01-05 02:32:27 +0800 CST
  • Martin Hope
    Patrick 如何优化大型数据库的 mysqldump? 2011-01-04 13:13:48 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve