ruby-on-rails Ruby -返回列中字符串最长的记录

bwitn5fc  于 2023-01-14  发布在  Ruby
关注(0)|答案(2)|浏览(146)

我只需要product_description列中字符串最长的记录。
记录的product_description列中可能包含nil
所以这行不通:

Product.where(parent_product_id: 22033).pluck(:product_description).max_by(&:length)

然后我尝试SQL并得到:

ActiveRecord::UnknownAttributeReference (Query method called with non-attribute argument(s): "max(length(product_description))")

根据此查询:

Product.where(parent_product_id: 22033).pluck("max(length(product_description))")

这将返回相同的结果:

Product.where(parent_product_id: 22033).order("MAX(CHAR_LENGTH(product_description)) desc").limit(1)

但是product_description肯定是Products表中的一列,这不是问题所在

dz6r00yl

dz6r00yl1#

您可以使用RDBMS的length函数计算长度,然后按其排序。

领带

可能有许多产品具有相同的说明长度。为了获得一致的结果,您将需要一个平局决胜局,否则将不会定义具有相同说明长度的产品内的顺序。您可以通过id子句分配顺序。

空值

请注意

select length(null)

将返回null而不是0
null可能排在实际值之前或之后(取决于RDBMS及其配置)。
如果你总是需要一个数值,你可以

select length(coalesce(null, ''))

它将返回0
coalesce返回第一个non-null参数,因此确保我们总是至少传递一个空字符串给length
还可以对order子句使用null last选项。
也可以排除说明值为null的记录:

products = Product.where.not(product_description: nil)

以避免一起处理id值。
如果列不可空,则也没有问题。
现在如果你用这个:

products = Product.all # or whatever conditions you need
products
  .order("length(coalesce(product_description, '')) desc")
  .order(id: :asc)
  .first

那么Rails可能会抱怨(取决于您使用的版本)安全原因,比如ActiveRecord::UnknownAttributeReference: Dangerous query method
这意味着你需要把所有的东西 Package 在Arel.sql

products = Product.all # or whatever conditions you need
products
  .order(Arel.sql("length(coalesce(product_description, '')) desc"))
  .order(id: :asc)
  .first

指数

如果你有很多记录,你可能需要在列长度上添加一个索引。关于如何创建一个基于函数的索引,请参见https://sqlfordevs.com/function-based-index

ovfsdjhp

ovfsdjhp2#

你可以按长度点,这样先拿

Product
  .where(parent_product_id: 22033)
  .where.not(product_description: nil)
  .order("LENGTH(product_description) DESC")
  .first

LENGTH是RDBMS函数,取决于特定系统,因此可能有所不同

相关问题