我需要选择最近评论过的文章,每篇文章的最后一条评论,即包含max(c.created)
的行的其他列:
SELECT a.id, a.title, a.text, max(c.created) AS cid, c.text?
FROM subscriptions s
JOIN articles a ON a.id=s.article_id
JOIN comments c ON c.article_id=a.id
WHERE s.user_id=%d
GROUP BY a.id, a.title, a.text
ORDER BY max(c.created) DESC LIMIT 10;
Postgres告诉我,我必须将c.text放入GROUP BY。显然,我不想这样做。最小/最大也不合适。我不知道如何选择这个。
请建议。
答案 0 :(得分:2)
在PostgreSQL中,DISTINCT ON
可能是此类查询的最佳解决方案:
SELECT DISTINCT ON (a.id)
a.id, a.title, a.text, c.created, c.text
FROM subscriptions s
JOIN articles a ON a.id = s.article_id
JOIN comments c ON c.article_id = a.id
WHERE s.user_id = %d
ORDER BY a.id, c.created DESC
这将检索包含最新评论和相关附加列的文章 此closely related answer中的说明,链接和基准。
要获取最新的10,请将其包装在子查询中:
SELECT *
FROM (
SELECT DISTINCT ON (a.id)
a.id, a.title, a.text, c.created, c.text
FROM subscriptions s
JOIN articles a ON a.id = s.article_id
JOIN comments c ON c.article_id = a.id
WHERE s.user_id = 12
ORDER BY a.id, c.created DESC
) x
ORDER BY created DESC
LIMIT 10;
或者,您可以将window functions与标准 DISTINCT
结合使用:
SELECT DISTINCT
a.id, a.title, a.text, c.created, c.text
,first_value(c.created) OVER w AS c_created
,first_value(c.text) OVER w AS c_text
FROM subscriptions s
JOIN articles a ON a.id = s.article_id
JOIN comments c ON c.article_id = a.id
WHERE s.user_id = 12
WINDOW w AS (PARTITION BY c.article_id ORDER BY c.created DESC)
ORDER BY c_created DESC
LIMIT 10;
这是有效的,因为DISTINCT
(与聚合函数不同)应用了after
窗口函数
你必须测试哪个更快。我猜最后一个比较慢。