我有3个表:user,recommended(post_id,user_id),post
当用户对帖子进行投票时,会使用post_id,user_id和vote值创建新的推荐记录。
我想要一个查询,显示用户尚未看到/投票的随机帖子。
我的想法是,它需要将用户的所有推荐加入到帖子表中......然后选择没有加入推荐的记录。不知道如何做到这一点......
到目前为止,我确实无法工作:
SELECT "posts".*
FROM "posts"
INNER JOIN "recommendations" ON "recommendations"."post_id" = "posts"."id"
ORDER BY RANDOM()
LIMIT 1
答案 0 :(得分:2)
您可以使用左外连接执行此操作:
SELECT p.*
FROM posts p LEFT OUTER JOIN
recommendations r
ON r.post_id = p.id and r.userid = YOURUSERID
WHERE r.post_id IS NULL
ORDER BY RANDOM()
LIMIT 1;
请注意,我通过删除双引号(标识符名称不需要)和添加表别名来简化查询。这些更改使查询更容易编写和阅读。
答案 1 :(得分:1)
有几种很好的方法可以排除已经有给定用户推荐的行:
Select rows which are not present in other table
重要的问题是:任意或随机?
对于任意选择(任何符合条件的行都足够好),这应该是最便宜的:
SELECT *
FROM posts p
WHERE NOT EXISTS (
SELECT 1
FROM recommendations
WHERE post_id = p.id
AND user_id = $my_user_id
)
LIMIT 1;
很多帖子的排序步骤可能很昂贵(而且不必要)。在这种使用情况下,大多数帖子通常不会有来自用户的推荐。您每次都必须按random()
排序所有这些行
如果任何帖子没有推荐就足够了,那么删除ORDER BY
会使速度提高得快。 Postgres可以返回它找到的第一个合格帖子。
答案 2 :(得分:0)
因此您需要一组已推荐的帖子EXCEPT。
SELECT p.id FROM posts p
EXCEPT
SELECT r.post_id FROM recommendations r WHERE r.user_id = X
...