О, я понимаю, что вы имеете в виду. Да, я пробовал это с другими именами. Это не влияет на результаты.
ужно объединить таблицу с запросом выбора / группировки (который включает в себя ту же таблицу), и я хотел бы сделать это с помощью 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 (...)"
?