2011-01-21 104 views
3

我试图在PostgreSQL中编写查询,并且因为它适用于其他数据库引擎而感到有点沮丧。我需要从一个给定的连接的表像这样选择前5名用户:postgreSQL选择未在聚合函数中使用的其他列

 
SELECT users.*, 
     COUNT(deals.id) AS num_deals 
FROM users, deals 
WHERE deals.users_id = users.id 
GROUP BY users.id 
ORDER BY num_deals LIMIT 5; 

我所需要的前5名用户。这段代码可以在sqlite,mysql等工作,但PostgreSQL拒绝选择其他字段在集合函数中不使用。我收到以下错误:

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

如何在PostgreSQL中执行此操作?

+2

我相信它工作在MySQL和SQLite但“等”是错的。没有其他数据库允许这个。这是唯一的两个。 – 2011-01-21 08:02:26

+1

其实,假设users.id是一个主键,它是*不*错。 (尽管MySQL在正确和错误的时候都会这样做)。 PostgreSQL 9.1将支持按照其编写的方式运行此查询 - 因为GROUP BY位于PRIMARY KEY上,所以我们可以推断出所有其他列在功能上依赖于它。 – 2011-01-21 09:58:15

+0

@Magnus:我知道9.1会支持这个,但9.1目前还不可用 – 2011-01-21 14:26:39

回答

7

你可以尝试:

SELECT users.*, a.num_deals FROM users, (
    SELECT deal.id as dealid, COUNT(deals.id) AS num_deals 
    FROM deals 
    GROUP BY deal.id 
) a where users.id = a.dealid 
ORDER BY a.num_deals DESC 
LIMIT 5 
2

假设users.id是PK,那么你可以

等待9.1

组由各个领域的

使用聚合(即max())所有字段

1

另一个解决方案,工作我s到暗中使用的所有属性在GROUP BY

因此下面将是最终的查询

SELECT users.*, 
     COUNT(deals.id) AS num_deals 
FROM users, deals 
WHERE deals.users_id = users.id 
GROUP BY users.id, users.name, users.attrib1, ..., users.attribN 
ORDER BY num_deals LIMIT 5; 

如果您使用的是像Rails框架,那么你可以很容易地这与Model.column_names功能实现。

0

只是在有人的情况下,希望ANSI-92标准的解决方案,不喜欢“甲骨文”的方式来连接表...

SELECT users.*, num_deals 
FROM users 
JOIN 
    (SELECT deals.users_id as users_id, count(deals.users_id) as num_deals 
    FROM deals 
    GROUP BY deals.id) grouped_user_deals 
ON grouped_user_deals.users_id = users.id 
ORDER BY num_deals DESC 
LIMIT 5; 
相关问题