【问题标题】:SQL float columns: select "where x = 2.0" works, but "where x = 2.1" does notSQL 浮点列:选择 "where x = 2.0" 有效,但 "where x = 2.1" 无效
【发布时间】:2019-09-24 20:59:31
【问题描述】:

我有一个模型为Project 的Ruby on Rails 应用程序,它的属性wcag_version 的类型为float。

我有wcag_version = 2 的记录和wcag_version = 2.1 的记录:

我注意到的是,Rails 使用 Project.where(wcag_version: 2.0) 找到带有 wcag_version = 2 的记录:

[4] pry(#<WcagElementsController>)> Project.where(wcag_version: 2.0)
=> [
    [0] #<Project:0x007f9fa900c6e8> { :id => 1 ... }

但是使用Project.where(wcag_version: 2.1)找不到wcag_version = 2.1的记录:

[5] pry(#<WcagElementsController>)> Project.where(wcag_version: 2.1)
=> []

这似乎是一个 SQL 问题,而不是 Rails 问题。生成的 SQL 是:

[6] pry(#<WcagElementsController>)> Project.where(wcag_version: 2.1).to_sql
=> "SELECT `projects`.* FROM `projects` WHERE `projects`.`wcag_version` = 2.1 ORDER BY `projects`.`name` ASC"

如果我直接在数据库上手动执行它也不会返回任何内容:

这里发生了什么?顺便说一句,我正在使用 MySQL。

【问题讨论】:

  • 改用十进制/数字数据类型。 (如果支持。)浮点值 2.1 保存为 2.0999999E+00 的东西。
  • 花车很烂。对于一个版本,我会将其保存为 varchar。如果你最终得到2.1.1 或类似的版本怎么办?
  • 不要使用数字表示版本。使用VARCHAR。您将如何将版本 3.12.0.7-beta2.1-SNAPSHOT 存储在数字中?尝试使用数字是在打一场你无法获胜的战斗。
  • 好点。但是如何比较这些 VARCHAR?
  • 对 Rails 一无所知,我会从 wcag_version = '2.1' 开始。字符数据的单引号(刻度线)。

标签: mysql sql ruby-on-rails floating-point


【解决方案1】:

处理 Rails,看来我可以解决这个问题:

Project.all.each do |project|
  if project.wcag_version >= reference_criterion.wcag_version
    # Do stuff
  end
end

虽然性能较差,但它为我省去了很多麻烦。

为了完整起见,这里是原始代码:

Project.where("wcag_version >= #{reference_criterion.wcag_version}").each do |project|
  # Do stuff
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-05
    • 1970-01-01
    相关资源
    最近更新 更多