我有一个Account
模型,其中包含role
列。
我希望按created_at
日期选择不同的角色(例如,在01.01.2018等创建的所有不同角色等)并仅获取列role
的值。
选择不同的角色可以很好地作为查询,但是当获取值时,我会得到意想不到的结果。
如果我只是在所有查询结果上使用map
函数,那么一切正常并且SQL查询看起来很好。
Account.where(id: 1..10).select(:created_at, :role).distinct.map(&:role)
Account Load (1.0ms) SELECT DISTINCT "accounts"."created_at", "accounts"."role" FROM "accounts" WHERE ("accounts"."id" BETWEEN $1 AND $2) [["id", 1], ["id", 10]]
=> ["admin", "manager", "manager", "manager", "manager", "manager", "manager", "manager", "manager"]
但是,如果我想将.map(&:role)
更改为.pluck(:role)
,根据定义,pluck
方法会删除第一个distinct
条件并仅保留distinct
我们可以在查询开头看到角色。
Account.where(id: 1..10).select(:created_at, :role).distinct.pluck(:role)
(0.7ms) SELECT DISTINCT "accounts"."role" FROM "accounts" WHERE ("accounts"."id" BETWEEN $1 AND $2) [["id", 1], ["id", 10]]
=> ["admin", "manager"]
在pluck
文档(apidock)中,只有当代码看起来像.pluck('distinct role')
为什么它在我的情况下是这样的?这是一些无证的功能吗?
答案 0 :(得分:2)
对你的问题的简短回答"为什么它在我的案例中是这样的?"是因为它应该像这样工作。你说:
在pluck文档中。 。 。它的编写,只有当代码看起来像
时,pluck才会使用distinct.pluck('distinct role')
这不准确。您引用的文档显示了一个这样的示例,作为采用DISTINCT
的方法,但并未说明这是唯一的方式来应用DISTINCT
SQL修饰符。由于您已将.distinct
添加到ActiveRecord
关系中,因此生成的查询将为SELECT DISTINCT
。这会提示SQL为您提供唯一值,而不是pluck
方法; pluck
只会返回您的数据库所提供的内容。
要了解pluck
使用created_at
和role
的不同组合后实现目标的方法,您可以改为使用group
:
Account.where(id: 1..10).group(:created_at, :role).pluck(:role)
# => SELECT "accounts"."role" FROM "accounts" WHERE ("accounts"."id" BETWEEN $1 AND $2) GROUP BY "accounts"."created_at", "accounts"."role" [["id", 1], ["id", 10]]
.group(:created_at, :role)
调用(添加GROUP BY
SQL子句)将根据created_at
和role
为您提供独特的行组合(相同的role
如果它与多个created_at
值相关联,则可能会多次出现。然后,.pluck(:role)
将仅采用role
的值。