英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论