О, я понимаю, что вы имеете в виду. Да, я пробовал это с другими именами. Это не влияет на результаты.

ужно объединить таблицу с запросом выбора / группировки (который включает в себя ту же таблицу), и я хотел бы сделать это с помощью Arel.

У меня есть стол:phenotypes которыеhas_and_belongs_to_many :genes, которые самиhas_and_belongs_to_many :orthogroups, В результате отношения между фенотипами и ортогруппами становятся многими ко многим.

У меня есть две области действия (на ортогруппе), которые получают все ортогруппы, связанные с определенным фенотипом:

  scope :with_phenotype, lambda { |phenotype_id|
    where("observations.phenotype_id = ?", phenotype_id).
      joins("inner join orthologies on (orthologies.orthogroup_id = orthogroups.id) inner join observations on (observations.gene_id = orthologies.gene_id)")
  }

  scope :with_associated_gene_ids_for_phenotype, lambda { |phenotype_id|
    with_phenotype(phenotype_id).
      select("orthogroups.id, array_agg(distinct observations.gene_id) as associated_gene_ids").
      group("orthogroups.id")
  }

Таким образом, делаяOrthogroup.with_associated_gene_ids_for_phenotype(48291) должен вернуть таблицу идентификаторов ортогрупп и генов, которые связывают их с фенотипами.

Это все работает отлично.

Вопрос в том, что я хотел бы получить остальную частьorthogroups.* и присоедините его к результатам второй области, так что список генов в основном похож на дополнительное поле в моей модели Orthogroup ActiveRecord.

Примерно как то так:

SELECT   o1.*, o_genes.associated_gene_ids
FROM     orthogroups o1
INNER JOIN (
  SELECT    o2.id, array_agg(DISTINCT obs.gene_id) AS associated_gene_ids
  FROM orthogroups o2
  INNER JOIN orthologies ortho ON (ortho.orthogroup_id = o2.id)
  INNER JOIN observations obs ON (ortho.gene_id = obs.gene_id)
  WHERE obs.phenotype_id = ? GROUP BY o2.id
) AS o_genes
ON (o1.id = o_genes.id);

Теперь этот запрос, кажется, работает. Но я бы предпочел найти способ присоединить таблицу Orthogroup непосредственно к своей области, чтобы получить эти гены.

Возможно, было бы проще использовать SQL, но похоже, что с Arel должен быть легкий путь. Я нашел несколько похожих вопросов, но ни на один, похоже, нет ответов.

Ближайшее решение, которое я нашел, это:

def self.orthogroups phenotype_id
  Orthogroup.select("orthogroups.*, o_genes.associated_gene_ids").
    joins(Arel.sql("inner join (" + Orthogroup.with_associated_gene_ids_for_phenotype(phenotype_id).to_sql + ") AS o_genes ON (o_genes.id = orthogroups.id)"))
end

Выведенный SQL использует таблицу «ортогруппы» в двух контекстах, и это меня беспокоило; однако выборочная проверка результатов показывает, что запрос правильный.

Тем не менее, это не элегантное решение, на которое я мог бы надеяться. Возможно ли это сделать без неловкого"inner join (...)"?

Ответы на вопрос(1)

Ваш ответ на вопрос