【问题标题】:Calculate the maximum number on a string column with active record计算具有活动记录的字符串列的最大数量
【发布时间】:2019-08-19 19:58:48
【问题描述】:

我的客户模型中有一个名为 internal_code 的列。由于某些用户可能将其用作字母数字,而其他用户仅将其用作数字,因此我需要在用户界面中确认之前向用户建议一个数字。

我现在正在使用这个代码:

previous_number = Company.where(:company_id => self.company_id).maximum(:internal_code)

但这并没有按预期工作,由于某种原因,有时它在最新值为“1000”时返回“999”,或者在另一个示例中,当最新值为“2291”时返回“2290”。

我一直在研究有关 Active Record 的 maximumcalculate 的官方文档,但没有发现它是否不适用于 String 列。也许这很明显,但在我确认我的想法之前我想在这里问一下。

【问题讨论】:

    标签: ruby ruby-on-rails-4 activerecord


    【解决方案1】:

    如果这是一个文本列,您可能会得到 ASCIIabetical“最大值”而不是数字最大值。 “999”排在“2291”之后。

    您需要一个数值列类型(例如INT)才能进行数值最大值。

    如果这些值是纯数字并且适合 32 位或 64 位整数,这应该是更改列类型的简单迁移。

    【讨论】:

    • 感谢stackoverflow.com/users/87189/tadman,但此列必须是字母数字。我提到过: > 一些用户可能会将其用作字母数字,而其他用户可能仅将其用作数字。但是 ASCIIabetical "max" 是有道理的,因为 "999" > "1000" = true
    • 如果您混合了字母和数字值,那么您需要定义派生的可排序值。例如,这可以是零填充,以使事情正确排列。数据库无法为您执行此操作,因为这些规则通常是模棱两可的:"A2A2" 是在 "A11A1" 之前还是之后?查看other examples 以获得灵感。
    【解决方案2】:

    我找到的最终解决方案:

    # Note: the ORDER clause is the KEY. Length means biggest number, ::bytea means sort it alphanumerically
    filtered_result = Company.where.not(:internal_code => [nil,'']).where(:company_id => self.company_id).order("length(internal_code) DESC, internal_code::bytea DESC").first
    
    previous_number = filtered_result.internal_code.scan(/\d{2,5}/).last
    

    之所以给出这种复杂性,是因为用户可以在此字段中输入可能的值。例如。 "ABD123" AS2134FG AS34SD2342

    希望它有助于解决类似的问题。谢谢大家。

    【讨论】:

      猜你喜欢
      • 2017-09-06
      • 2014-02-17
      • 1970-01-01
      • 1970-01-01
      • 2021-09-07
      • 1970-01-01
      • 1970-01-01
      • 2011-04-23
      • 1970-01-01
      相关资源
      最近更新 更多