postgresql 按常用标签查询相关帖子的SQL查询

tjvv9vkg  于 2023-03-01  发布在  PostgreSQL
关注(0)|答案(1)|浏览(99)

型号

tags
- name
- pid (short for post_id)
(fk = name + pid)

posts
- id
- title
- content
(all posts have minimum of 3 tags)
...

功能

create function get_related_posts(post_id uuid)
returns setof posts
language plpgsql
as $$
begin
    return query
    select 
    ... (what code goes here?)  
    posts.id = $1;
end;$$;

希望创建一个函数get_related_posts,它可以让我通过标签获得相关的帖子。
然后我可以使用Supabase在前端限制这些结果。
可能是这样的,但是用SQL?

伪代码

results = [];
Select all posts that have all 5 tags
  if any exist, add them to top of results array
loop through all possible sets of 4 tags
  select all posts that have these 4 tags
  if exists, add them to results array
loop through all possible sets of 3 tags
  select all posts that have these 3 tags
  if exists, add them to results array
loop through all possible results sets of 2 tags
  select all posts that have these 2 tags
  if exists, add them to results array
loop through all possible individual tags
  select all posts that have this one tag
  if exists, add them to the results array
return results

当然,如果我使用分页和限制,也不知道这将如何工作。
我无法理解这个...
J型

EDIT-我要查找的结果只是一组帖子记录...

| 识别号|职务|内容|
| - ------|- ------|- ------|
| 1个|职位|...|
| ...|...|...|
J型

ewm0tg9j

ewm0tg9j1#

像这样一步步解决问题
以下代码获取帖子ID的所有标记

select name 
 from tags
 where pid = $1

下面的代码获取了所有帖子的标签(每个帖子都有一行标签)。

select posts.id, tags.name 
 from posts
 join tags on posts.id = tags.pid

然后,我们可以将其加入到原始文件中的标记列表中,以获得具有匹配标记的所有项目

select posts.id, tags.name 
 from posts
 join tags on posts.id = tags.pid
 join (
   select name 
   from tags
   where pid = $1
 ) as match on match.name = tags.name

我们希望这些帖子按标签最多的帖子排序--如果我们按标签分组,我们可以得到匹配标签的计数并对它们进行排序。

select posts.id, count(*) as match_count 
 from posts
 join tags on posts.id = tags.pid
 join (
   select name 
   from tags
   where pid = $1
 ) as match on match.name = tags.name
 group by post.id
 order by match_count desc

关于像sql一样思考的一个简短说明sql是在集合中工作的这意味着你不使用if语句(像你的代码一样),而是使用过滤器或连接,正如你所看到的,我执行的每一步都是在整个数据集上进行的,而不是逐行查看。

相关问题