Sql 从“has_many”到-gt;{distinct}`由关联的值执行
我正在使用一个Sql 从“has_many”到-gt;{distinct}`由关联的值执行,sql,ruby-on-rails,postgresql,activerecord,Sql,Ruby On Rails,Postgresql,Activerecord,我正在使用一个SELECT DISTINCT,试图按关联值对结果排序时出现问题。以这个例子(在Rails中): 我有一个Cook模型,它与客户有着明显的关联: has_many :customers, -> { distinct }, through: :orders, source: :user 这很明显,因为我只想统计一次客户,即使他们有多个订单 为此生成的SQL为: > cook.customers.to_sql => "SELECT DISTINCT \"users\
SELECT DISTINCT
,试图按关联值对结果排序时出现问题。以这个例子(在Rails中):
我有一个Cook
模型,它与客户有着明显的关联:
has_many :customers, -> { distinct }, through: :orders, source: :user
这很明显,因为我只想统计一次客户,即使他们有多个订单
为此生成的SQL为:
> cook.customers.to_sql
=> "SELECT DISTINCT \"users\".* FROM \"users\"
INNER JOIN \"orders\" ON \"users\".\"id\" = \"orders\".\"user_id\"
INNER JOIN \"meals\" ON \"orders\".\"meal_id\" = \"meals\".\"id\"
WHERE \"meals\".\"cook_id\" = 1"
这个很好用!(通过膳食关联订单
表,但可以忽略)
我想根据这些客户订单的
价值创建的最新的来订购此客户列表。但当我这样做时,我会得到一个错误:
cook.customers.order('orders.created_at DESC').to_sql
=> "SELECT DISTINCT \"users\".* FROM \"users\"
INNER JOIN \"orders\" ON \"users\".\"id\" = \"orders\".\"user_id\"
INNER JOIN \"meals\" ON \"orders\".\"meal_id\" = \"meals\".\"id \"WHERE \"meals\".\"cook_id\" = 1 ORDER BY orders.created_at DESC"
> cook.customers.order('orders.created_at DESC')
ActiveRecord::StatementInvalid: PG::InvalidColumnReference: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list
LINE 1: ...eals"."id" WHERE "meals"."cook_id" = $1 ORDER BY orders.cre...
即使我显式地加入了表(因为有很多到),这仍然不起作用
cook.customers.joins(:orders).order('orders.created_at DESC').to_sql
=> "SELECT DISTINCT \"users\".* FROM \"users\" INNER JOIN \"orders\" \"orders_users\" ON \"orders_users\".\"user_id\" = \"users\".\"id\" INNER JOIN \"orders\" ON \"users\".\"id\" = \"orders\".\"user_id\" INNER JOIN \"meals\" ON \"orders\".\"meal_id\" = \"meals\".\"id\" WHERE \"meals\".\"cook_id\" = 1 ORDER BY orders.created_at DESC"
有什么线索吗?我正在寻找一个将返回ActiveRecord关系的解决方案(因此不要使用sort\u by
),因为我计划将其他查询链接到该关系
谢谢:)您不必手动指定连接条件,您可以通过使用includes
来完成,ActiveRecord将处理连接条件
cook.customers.includes(:orders).order('orders.created_at DESC').references(:orders).to_sql
您不必手动指定联接条件,您可以使用includes
来指定联接条件,ActiveRecord将处理联接条件
cook.customers.includes(:orders).order('orders.created_at DESC').references(:orders).to_sql
对我来说,这很有效。My model Apartment.rb具有默认范围排序
这不管用
has many :apartments
has_many :buildings, -> {distinct}, through: :apartments
确实如此
has many :apartments
has_many :buildings, through: :apartments
def buildings
super.uniq
end
对我来说,这很有效。My model Apartment.rb具有默认范围排序
这不管用
has many :apartments
has_many :buildings, -> {distinct}, through: :apartments
确实如此
has many :apartments
has_many :buildings, through: :apartments
def buildings
super.uniq
end
这实际上会产生与我之前得到的错误相同的错误:ActiveRecord::StatementInvalid:PG::InvalidColumnReference:error:for SELECT DISTINCT,ORDER BY表达式必须出现在select列表中。这实际上会产生与我之前遇到的相同错误:ActiveRecord::StatementInvalid:PG::InvalidColumnReference:error:对于select DISTINCT,ORDER BY表达式必须出现在选择列表中。使用.uniq
将对象从ActiveRecord\u关系更改为数组。这可能不太理想,你是对的。在我的例子中,这就足够了,我不需要这些关系,但感谢您指出了这一点。使用.uniq
将对象从ActiveRecord\u关系更改为数组。这可能不太理想,你是对的。就我而言,这就足够了,我不需要这些关系,但谢谢你指出这一点。