Rails 4查询由单个属性唯一
Posted
技术标签:
【中文标题】Rails 4查询由单个属性唯一【英文标题】:Rails 4 query unique by single attribute 【发布时间】:2013-08-05 16:40:46 【问题描述】:所以这更像是一个问题,但这就是我想要做的。
假设我有三个对象,称为 Items
<Item id: 1, name: 'Book'>
<Item id: 2, name: 'Car'>
<Item id: 3, name: 'Book'>
我想做一个只返回每个唯一“名称”属性之一的查询。
类似Item.select('distinct(name), items.*')
这不起作用,它仍然返回所有三个项目。
我怎样才能形成这个查询,以便它只返回:
<Item id: 1, name: 'Book'>
<Item id: 2, name: 'Car'>
【问题讨论】:
那么它应该返回哪个图书对象,1 还是 3? @sevenseacat 没关系,都可以。 【参考方案1】:如果你想取回整个模型,但仍然保持唯一性,你可以使用这个:
Item.select('distinct on (name) *')
我只用 Postgres 数据库对此进行了测试。它可能适用于 mysql,也可能不适用于 mysql。
【讨论】:
上面的答案将返回所有列,如果您只想选择某些列,您可以尝试使用Item.select('distinct on (name) name, id')
这太棒了!我一直在到处寻找这个:-)
我一直吓坏了,因为我意识到我只需要获取数据库中的最新记录,而且我应该向我的老板展示一些东西,但我一生都无法获得它可以工作,直到我找到这个。你是一个救生员,你!!!
有谁知道我如何用 mysql 实现这一点?
在mysql中:SELECT distinct on (name) * FROM items
【参考方案2】:
请试试这个:
Item.select('distinct name')
【讨论】:
那种作品。它返回仅具有“名称”属性的对象。我想返回整个对象。我明白了:如果你只需要一个有名字的数组,没有 ID,你可以这样做:
Item.pluck(:name).uniq
SQL查询结果:
#=> SELECT `items`.`name` FROM `items`
** 编辑 **
uniq
在记录数组上运行。如果您期望有很多记录,请小心。
SQL Distinct 要快得多。
如果是这样,请使用上面 vee 的答案,并带有 map
:
Item.select('distinct name').map(:name)
【讨论】:
【参考方案4】:我还不能对帖子发表评论,因此,将其作为问题的另一个答案。
如果有人仍在搜索此内容,@BananaNeil's answer 是正确的。但是,将distinct
放入select
对我不起作用(Rails 5.2.2)。将这两者分开确实解决了我的问题。
klass.where(
# Your query or whatever
).distinct.select('on (attribute) *')
【讨论】:
【参考方案5】:在 Rails 4 中尝试Items.all.to_a.uniq |item| item.name
在 Rails 3 中,您应该能够做到 Items.uniq_by |item| item.name
当您在数组上调用uniq
时,您可以向它传递一个块来指示如何确定唯一性。在 Rails 3 中,您曾经可以使用 uniq_by
,但在 Rails 4 中已弃用它。所以我发现的一种方法是将 ActiveRecord Relation 转换为数组并在其上调用 uniq
。
【讨论】:
这对于小型查询非常有用,但对于大型数据集来说性能很差。.to_a
一个将数据加载到内存中的查询真的很糟糕。【参考方案6】:
对于 Mysql,您可以使用 group
并禁用 ONLY_FULL_GROUP_BY,
Item.group(:name).to_sql
=> "SELECT `items`.* FROM `items` GROUP BY name"
见Is there ANY_VALUE capability for mysql 5.6?
【讨论】:
以上是关于Rails 4查询由单个属性唯一的主要内容,如果未能解决你的问题,请参考以下文章