嵌套查询在squeel中

简短版本:如何在squeel中编写此查询?

SELECT OneTable.*, my_count FROM OneTable JOIN ( SELECT DISTINCT one_id, count(*) AS my_count FROM AnotherTable GROUP BY one_id ) counts ON OneTable.id=counts.one_id 

long版本: rocket_tag是一个为模型添加简单标记的gem。 它添加了tagged_with方法。 假设我的模型是User ,带有id和name,我可以调用User.tagged_with ['admin','sales'] 。 在内部它使用这个吱吱声代码:

 select{count(~id).as(tags_count)} .select("#{self.table_name}.*"). joins{tags}. where{tags.name.in(my{tags_list})}. group{~id} 

哪个生成此查询:

 SELECT count(users.id) AS tags_count, users.* FROM users INNER JOIN taggings ON taggings.taggable_id = users.id AND taggings.taggable_type = 'User' INNER JOIN tags ON tags.id = taggings.tag_id WHERE tags.name IN ('admin','sales') GROUP BY users.id 

一些RDBMS对此很满意,但postgres抱怨:

 ERROR: column "users.name" must appear in the GROUP BY clause or be used in an aggregate function 

我相信编写查询的更方便的方法是:

 SELECT users.*, tags_count FROM users INNER JOIN ( SELECT DISTINCT taggable_id, count(*) AS tags_count FROM taggings INNER JOIN tags ON tags.id = taggings.tag_id WHERE tags.name IN ('admin','sales') GROUP BY taggable_id ) tag_counts ON users.id = tag_counts.taggable_id 

有没有办法用squeel表达这个?

我不知道Squeel,但你看到的错误可以通过升级PostgreSQL来解决。

一些RDBMS对此很满意,但postgres抱怨:

错误:列“users.name”必须出现在GROUP BY子句中或用于聚合函数

从PostgreSQL 9.1开始,一旦在GROUP BY中列出主键,就可以跳过此表的其他列,并仍然在SELECT列表中使用它们。 版本9.1的发行说明告诉我们:

在GROUP BY子句中指定主键时,在查询目标列表中允许非GROUP BY列


顺便说一句,您的替代查询可以简化,额外的DISTINCT将是多余的。

 SELECT o.*, c.my_count FROM onetable o JOIN ( SELECT one_id, count(*) AS my_count FROM anothertable GROUP BY one_id ) c ON o.id = counts.one_id