【问题标题】:Advanced Active Record order by using regex使用正则表达式的高级 Active Record 订单
【发布时间】:2016-11-17 19:17:21
【问题描述】:

我正在尝试查询我的订单模型以获取所有记录,但我希望它们以非常具体的方式排序。

数据库是一个 PostgreSQL 数据库。

我想要所有以NY 开头的记录,然后是NYN,然后是所有剩余的记录。

我想我正在尝试做这样的事情:

Order.all.order('order_number /^NY/, /^NYN/')

数据示例:

NY-1111111
NYN-1234567
P-000000
P0000000
SS0232131
NYN16151202

我想要的顺序是:

NY-1111111
NYN16151202
NYN-1234567
P0000000
P-000000
SS0232131

【问题讨论】:

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


    【解决方案1】:

    你可以通过这样的 ruby​​ sort_by 方法做到这一点:

    orders = Order.all.sort_by{ | order |
        if order.name =~ /^NYN/
            -1;
        elsif order.name =~ /^NY/
            -2;
        else
            0;
        end
    }
    

    因此,如果订单名称为:["ghi", "NYabc", "jk", "NYNdef"],则订单将为:["NYabc", "NYNdef", "ghi", "jk"]["NYabc", "NYNdef", "jk", "ghi"]

    你可以找到sort_by here的文档

    希望对你有帮助:)

    【讨论】:

    • 感谢您的回答。它非常接近我想要实现的目标。我现在的问题是我需要返回值是一个 ActiveRecord 对象而不是一个数组,这就是为什么我想尝试使用 ActiveRecord 查询来完成查询。
    • @VinnyAlfieri 欢迎 .. 很高兴它有帮助 :)
    • 这是非常低效的。您正在从数据库中提取所有记录,在 Ruby 中对它们进行排序,然后再次从数据库中提取所有记录。没有理由不在查询中进行排序,只获取一次记录。
    • @jordan 如果您对如何在一个查询中执行此操作有任何线索,我将不胜感激。
    • 您确定Order.find([1,2,3]) 保证返回1,2,3 订单中的模型吗?如果您已经拥有它们,为什么还要重新获取它们?
    【解决方案2】:

    这是您可以在 SQL 中执行此操作的一种方法:

    SELECT * FROM orders
      ORDER BY
        CASE
          WHEN order_number LIKE 'NYN%' THEN 1
          WHEN order_number LIKE 'NY%' THEN 0
          ELSE 2
        END,
        order_number;
    

    这可以直接转化为 ActiveRecord 查询:

    Order.order("
      CASE
        WHEN order_number LIKE 'NYN%' THEN 1
        WHEN order_number LIKE 'NY%' THEN 0
        ELSE 2
      END,
      order_number
    ")
    

    这是使用 PostgreSQL 的 POSIX 正则表达式的另一种可能性。我不确定它与上述性能相比如何:

    Order.order("
      CASE SUBSTRING(order_number FROM '^NYN?')
        WHEN 'NY' THEN 0
        WHEN 'NYN' THEN 1
        ELSE 2
      END,
      order_number
    ")
    

    【讨论】:

    • 加 1 .. 非常好的和有效的答案:)
    • 高效正确。第二部分有时很重要;)
    • 很棒的@jordan。非常感谢您。这样效率更高,效果更佳。
    • 很高兴为您提供帮助。我为我的答案添加了第二个解决方案。如果您有一个大型数据集,我会很好奇哪个表现更好。
    • @VinnyAlfieri 我已经编辑了我的答案,因为我意识到我的 NY/NYN 顺序倒退了(我把“NYN”放在第一位)。另外,仅供参考,我只是注意到在您的示例中,“NYN-12 ...”之前有“NYN16 ...”,“PP-00 ...”之前有“PP00 ...”,我的回答没有t 地址。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-26
    • 2016-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多