2012-03-19 48 views
3

短版本:如何在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 

龙版本:rocket_tag是,增加了简单的标签,以模型的瑰宝。它增加了一个方法tagged_with。假设我的模型是User,带有一个ID和名称,我可以调用User.tagged_with ['admin','sales']。在内部它使用此squeel代码:

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来表达这个吗?

+0

你是什么PostgreSQL版本? – 2012-03-19 07:22:09

回答

2

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

Some RDBMSs are happy with this, but postgres complains:

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

从PostgreSQL 9.1开始,一旦你列出的组的主键由用户可以跳过其它列此表,并仍然在SELECT列表中使用它们。该release notes for version 9.1告诉我们:

Allow non-GROUP BY columns in the query target list when the primary key is specified in the GROUP BY clause


顺便说一句,你选择的查询可以被简化,另外的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 
+0

真的很高兴知道,谢谢!不幸的是,我在heroku上运行应用程序,所以从8.3升级到9.1将会花费我每月至少200美元,但如果问题是特定于旧版本的postgres,那么我想我会接受我必须解决的find_by_sql。尽管如果squeel可以用于这种查询,我仍然很好奇。 – dslh 2012-03-19 10:20:32

+0

@dslh:[Heroku Labs已经提供9.1](http://devcenter.heroku.com/articles/labs-heroku-shared-postgresql)。你可能会感兴趣。 – 2012-03-19 12:46:46

+0

这不回答我的问题,但它确实解决了我的问题。我想我问的是错误的问题。非常感谢! – dslh 2012-03-22 20:02:47