【问题标题】:Delete a row where its primary key is closest to X删除主键最接近 X 的行
【发布时间】:2011-02-25 23:05:25
【问题描述】:

我正在尝试删除一行,例如其主键(列名=版本)为 4.002000000000001。所以我给出声明:

DELETE FROM tbl WHERE version=4.002;

现在这行不通,因为没有版本等于 4.002 的行,只有版本等于 4.002000000000001 的行。 请不要问我为什么不存储数据库中的版本为 4.002,因为我试图通过使列类型为 DECIMAL(5,3) 来做到这一点,但它仍然将 Java 中的双精度值存储为 4.002000000000001。请不要问我为什么不说“...WHERE version=4.002000000000001;”因为现在当我使用 JDBC 创建语句时,我无法控制 java 格式如何加倍(即使使用 DecimalFormat 类)。

那么有没有办法在 SQLite3 中四舍五入(地板函数)?那么我可以说“删除 FLOOR(version) 等于 4.002 的行?

我是一名 C++ 程序员(使用 Java 查询 SQL 数据库,请不要问为什么:P),不精通复杂的 SQL 查询,所以这对于我想做的事情是否正确:

DELETE FROM tbl WHERE ROUND(version, 0.5)=4.002;

【问题讨论】:

  • 天哪。映射到 double 的十进制 PK。那是......非常令人担忧。
  • 我应该使用不同的 Java 数据类型吗?漂浮?也许是字符串?我知道拥有 SQL 十进制主键很糟糕,但我正在更新一个大型现有项目,并且在框架内工作比重新设计和重新开始更好。
  • 我同意@Kirk .. 你应该退后一步,深呼吸几下,问问自己到底为什么要使用非整数作为主键。
  • 在这些深呼吸之后,继续并回顾你的旧问题并接受一些答案。
  • 这就像在汽车论坛上问“请告诉我如何安装第二个油门踏板让我的车开得更快,不要问我为什么选择这种方法让我的车开得更快"。

标签: java sql jdbc sqlite


【解决方案1】:

请不要问我为什么不说“...WHERE version=4.002000000000001;”因为现在我无法控制 java 格式如何加倍(即使使用 DecimalFormat 类)

我不会。

但我会问你为什么使用double 来存储版本号。

机器浮点类型(以 2 为底)不包含精确的十进制数。但版本号字符串是准确的。根据您的版本编号方案,您最好将版本“编号”视为以下之一:

  • 缩放整数;例如4.002 等于 4002 除以 1000。您可能不需要明确存储比例因子。
  • 元组或整数数组;例如4.002{4,2}。这允许将 4.003.005 等版本号表示为 {4,3,5} 等。
  • 受模式约束的字符串;例如4.002 是一个匹配正则表达式 "\d+\.\d\d\d" 的字符串。这允许版本字符串包含非数字部分。

选择其中之一,您就不必担心浮点类型在内存或数据库中的基本不精确性质。


哦,顺便说一句,DecimalFormat确实让您在格式化数字时控制小数点后的位数。您可以使用模式或调用 setMaximumFractionDigits

来指定它

【讨论】:

    【解决方案2】:

    你可以吗?

    DELETE FROM tbl WHERE version > 4.002 - 1e-4 AND version < 4.002 + 1e-4
    

    DELETE FROM tbl WHERE version > 4.0015 AND version < 4.0025
    

    【讨论】:

      【解决方案3】:
      DELETE FROM tbl WHERE abs(version-4.002)<.0001
      

      如果您想删除 .0001 的 epsilon 边界内的所有版本

      【讨论】:

        猜你喜欢
        • 2017-03-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-24
        • 1970-01-01
        • 2017-02-12
        • 2019-01-04
        • 2010-09-06
        相关资源
        最近更新 更多