Sql 在一个查询中Rails左连接和内部连接

Sql 在一个查询中Rails左连接和内部连接,sql,ruby-on-rails,ruby,postgresql,ruby-on-rails-5,Sql,Ruby On Rails,Ruby,Postgresql,Ruby On Rails 5,问题是如何查找没有关联的所有记录,或者关联字段不等于给定字符串的所有记录: class Group < ApplicationRecord has_many :administration_groups has_many :administrations, through: :administration_groups end class AdministrationGroup < ApplicationRecord belongs_to :administration

问题是如何查找没有关联的所有记录,或者关联字段不等于给定字符串的所有记录:

class Group < ApplicationRecord
  has_many :administration_groups
  has_many :administrations, through: :administration_groups
end

class AdministrationGroup < ApplicationRecord
  belongs_to :administration
  belongs_to :group
end

class Administration < ApplicationRecord
  has_many :administration_groups
  has_many :groups, through: :administration_groups
end
我有这两个查询,但我不能将它们组合起来得到所需的结果。感谢您的帮助

尝试以下查询:

groups = Group.left_joins(:administrations).where(
  "administrations.id is NULL OR
   administrations.administration_type != ?", params[:type]
)

您只需使用这两个查询中的ID,就可以使用
ActiveRecord::Relations
合并在一起,如下所示:

Group.where.not(id: 
  Group.joins(:administration_groups)
  .pluck(:id)
).or(
Group.where(id: 
  Group
    .joins(administration_groups: :administration)
       .where.not(administrations: {administration_type: params[:type]}).pluck(:id)
)) 
这将导致类似的查询

 SELECT 
   [groups].*
 FROM 
   [groups] 
 WHERE
   ([groups].[id] NOT IN (
      SELECT 
         [groups].[id] 
      FROM 
         [groups] 
         INNER JOIN [administration_groups] 
           ON [administration_groups].[group_id] = [groups].[id])
   ) OR (
     [groups].[id] IN ( 
     SELECT 
         [groups]. [id] 
     FROM 
         [groups] 
         INNER JOIN [administration_groups] 
            ON [administration_groups].[group_id] = [groups].[id]
         INNER JOIN [administrations] 
           ON [administrations].[id] = [administration_groups].[administration_id] 
     WHERE 
           [administrations].[administration_type] <> YOUR_PARAMS_TYPE)
  )
这将导致

SELECT 
  [groups].*
FROM 
  [groups]
WHERE 
  [groups].[id] NOT IN (
     SELECT 
         [groups]. [id] 
     FROM 
         [groups] 
         INNER JOIN [administration_groups] 
            ON [administration_groups].[group_id] = [groups].[id]
         INNER JOIN [administrations] 
           ON [administrations].[id] = [administration_groups].[administration_id] 
     WHERE 
           [administrations].[administration_type] = YOUR_PARAMS_TYPE
  )

由于[administration_groups]上的内部联接已经删除了空值,因此类型检查将包括您不希望包括的其他ID

是否要合并
组\u 1
组\u 2
的两个记录?@Vishal yes。但是,如果只有一个查询,则此查询不会返回没有administrations@A.Chile我已更新了答案,请立即检查。
ArgumentError(传递给#的关系或必须在结构上兼容。不兼容的值:[:left_outer_joins,:references])
@A.Chile使用基于id的子查询作为条件,使用不同的解决方案进行更新。
Group.where.not(id: 
  Group
    .joins(administration_groups: :administration)
       .where(administrations: {administration_type: params[:type]}).pluck(:id))
SELECT 
  [groups].*
FROM 
  [groups]
WHERE 
  [groups].[id] NOT IN (
     SELECT 
         [groups]. [id] 
     FROM 
         [groups] 
         INNER JOIN [administration_groups] 
            ON [administration_groups].[group_id] = [groups].[id]
         INNER JOIN [administrations] 
           ON [administrations].[id] = [administration_groups].[administration_id] 
     WHERE 
           [administrations].[administration_type] = YOUR_PARAMS_TYPE
  )