我正在尝试在PostgreSQL中编写一个查询,但我有点沮丧,因为它可以在其他数据库引擎中运行。我需要从给定的连接表中选择前5个用户,如下所示:
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中执行此操作?
答案 0 :(得分: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
答案 1 :(得分:2)
假设users.id是PK,那么你可以
等待9.1
按所有字段分组
在所有字段上使用聚合(即max())
答案 2 :(得分:2)
另一个有效的解决方案是在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函数轻松实现此功能。
答案 3 :(得分:0)
如果有人想要ANSI-92标准解决方案并且不喜欢'Oracle'加入表格的方式......
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;