SQL查询以查找类别中的前3个

时间:2015-12-07 22:58:19

标签: sql postgresql greatest-n-per-group

致电所有sql爱好者! 快速信息:使用PostgreSQL。

我有一个查询返回每个类别的用户的最大匹配数。 我现在想要的是向每个类别展示最喜欢的前3位用户。

有用的resource正在使用此示例来解决问题:

select type, variety, price
from fruits
where (
   select count(*) from fruits as f
   where f.type = fruits.type and f.price <= fruits.price
) <= 2;

我理解这一点,但我的查询是使用连接,我也是初学者,所以我无法有效地使用这些信息。

开始营业,这是我为每个类别的用户返回MAX喜欢的查询。

SELECT category, username, MAX(post_likes) FROM (
SELECT c.name category, u.username username, SUM(p.like_count) post_likes, COUNT(*) post_num
FROM categories c
JOIN topics t ON c.id = t.category_id
JOIN posts p ON t.id = p.topic_id
JOIN users u ON u.id = p.user_id
GROUP BY c.name, u.username) AS leaders
WHERE post_likes > 0
GROUP BY category, username
HAVING MAX(post_likes) >= (SELECT SUM(p.like_count) 
                          FROM categories c 
                          JOIN topics t ON c.id = t.category_id 
                          JOIN posts p ON t.id = p.topic_id 
                          JOIN users u ON u.id = p.user_id WHERE c.name = leaders.category
GROUP BY u.username order by sum desc limit 1)
ORDER BY MAX(post_likes) DESC;

非常感谢任何和所有帮助。我很难解决这个问题。谢谢!

1 个答案:

答案 0 :(得分:0)

如果您希望每个类别最喜欢,请使用窗口功能:

SELECT cu.*
FROM (SELECT c.name as category, u.username as username, 
             SUM(p.like_count) as post_likes, COUNT(*) as post_num,
             ROW_NUMBER() OVER (PARTITION BY c.name ORDER BY COUNT(*) DESC) as seqnum
      FROM categories c JOIN
           topics t
           ON c.id = t.category_id JOIN
           posts p
           ON t.id = p.topic_id JOIN
           users u
           ON u.id = p.user_id
      GROUP BY c.name, u.username
     ) cu
WHERE seqnum <= 3;

即使有联系,每个类别也会返回三行。如果您想要做其他事情,请考虑DENSE_RANK()RANK()而不是ROW_NUMBER()

另外,在as子句中使用FROM列别名。虽然是可选的,但有一天你会留下逗号并感​​激你养成使用as的习惯。