SQL查询以标签共同点相关的帖子

huangapple go评论74阅读模式
英文:

SQL Query for Related Posts by Tags in Common

问题

以下是您要翻译的内容:

模型

tags
- name (名称)
- pid (缩写:post_id,帖子ID)
(fk = name + pid)

posts
- id (ID)
- title (标题)
- content (内容)
(所有帖子至少有3个标签)
...

功能

创建函数 get_related_posts(post_id uuid)
返回 posts 集合
语言 plpgsql
如下:
开始
    返回查询
    选择
    ... (这里放什么代码?)
    posts.id = $1;
结束;$$;

希望创建一个名为 get_related_posts 的函数,该函数允许我根据标签获取相关帖子。

然后,我可以在前端使用 Supabase 来限制这些结果。

所以可能类似于以下内容,但使用 SQL 编写?

伪代码

results = [];
选择所有具有所有5个标签的帖子
  如果存在任何帖子将它们添加到结果数组的顶部
循环遍历所有可能的4个标签集
  选择所有具有这4个标签的帖子
  如果存在将它们添加到结果数组中
循环遍历所有可能的3个标签集
  选择所有具有这3个标签的帖子
  如果存在将它们添加到结果数组中
循环遍历所有可能的2个标签集
  选择所有具有这2个标签的帖子
  如果存在将它们添加到结果数组中
循环遍历所有可能的单个标签
  选择所有具有这一个标签的帖子
  如果存在将它们添加到结果数组中
返回结果

当然,如果我使用分页和限制,也不清楚这将如何工作。

无法理解这个...

J

编辑 - 我要寻找的结果只是一组帖子记录...

ID Title Content
1 帖子1 标题 ...
... ... ...

J

英文:

Model

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

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

Function

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;$$;

Looking to create a function get_related_posts, which lets me get the related posts by tag.

And then I could limit those results on the front end using Supabase.

So maybe something like this, but in SQL?

pseudocode

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

Of course, if I used paging and limit, no idea either how this would work.

Can't wrap my head around this...

J

EDIT - The results I am looking for are just a set of posts records...

ID Title Content
1 post1 title ...
... ... ...

J

答案1

得分: 1

解决问题的方法是逐步进行的。

以下是获取帖子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

我们希望这些帖子按具有最多标签的顺序排列 - 如果我们使用GROUP BY,可以获得匹配标签的计数并对其进行排序:

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 posts.id
order by match_count desc

关于像SQL一样思考的一点说明 - SQL是基于集合的,这意味着你不使用if语句(就像你的代码一样),而是使用过滤器或连接。正如你可以看到,我执行的每个步骤都是在整个数据集上进行的,而不是逐行查看。

英文:

Solve problems like this step by step

The following gets all tags for a post ID

 select name 
 from tags
 where pid = $1

The following gets the tags of all posts (there will be a row per post that has a tag.

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

we can then join it to the list of tags in the original to get all items that have a matching tag

 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

we want these posts ordered by the ones with the most tags -- if we group by we can get a count of matching tags and order them.

 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

A quick note on thinking like sql -- sql works in sets -- this means you don't use if statements (like your code) but instead filters or joins. As you can see each step I performed was over an entire set of data -- not looking at row by row.

huangapple
  • 本文由 发表于 2023年2月27日 06:04:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/75575281.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定