如何解决SQL - 按来自多个表的信息对表进行排序
问题的标题可能不是很清楚 - 我不确定如何命名这个问题,但我希望我的解释能让我的问题更清楚。
我有 3 张桌子:
[1] 得分
id | rating_type |
---|---|
1 | UPVOTE |
2 | UPVOTE |
3 | DOWNVOTE |
4 | UPVOTE |
5 | DOWNVOTE |
6 | DOWNVOTE |
[2] post_score
post_id | score_id |
---|---|
1 | 1 |
1 | 2 |
1 | 3 |
2 | 4 |
2 | 5 |
2 | 6 |
和 [3] 发布
id | title |
---|---|
1 | title1 |
2 | title2 |
我的目标是按分数排序 [3] 发布表。
假设UPVOTE代表值为1,DOWNVOTE值为-1;在这个例子中,id = 1 的帖子有 3 个与之相关的分数,它们的值分别是 UPVOTE、UPVOTE、DOWNVOTE,构成了这个帖子的“数字分数”:2;
同样,id = 2 的帖子也有 3 个分数,这些值分别是:UPVOTE、DOWNVOTE、DOWNVOTE,构成“数字分数”:-1;
我将如何按此分数订购 post table?在这个例子中,如果我按分数 asc 排序,我希望得到以下结果:
id | title |
---|---|
2 | title2 |
1 | title1 |
我的尝试并没有走多远,我目前被这个查询困在这里,它并没有真正做任何有用的事情:
WITH fullScoreInformation AS (
SELECT * FROM score s
JOIN post_score ps ON s.id = ps.score_id),upvotes AS (SELECT * FROM fullScoreInformation WHERE rating_type = 'UPVOTE'),downvotes AS (SELECT * FROM fullScoreInformation WHERE rating_type = 'DOWNVOTE')
SELECT p.id,rating_type,title FROM post p JOIN fullScoreInformation fsi on p.id = fsi.post_id
我正在使用 PostgreSQL。查询将在我的 Spring Boot 应用程序中使用(我通常使用原生查询)。
也许这个数据结构很糟糕,我应该以不同的方式构建我的实体?
解决方法
我的目标是按分数对帖子表进行排序。假设 UPVOTE 代表 1 的值,DOWNVOTE 代表 -1 的值
一个选项使用子查询来计算每个帖子的赞成票和反对票:
select p.*,s.*
from post p
cross join lateral (
select
count(*) filter(where s.rating_type = 'UPVOTE' ) as cnt_up,count(*) filter(where s.rating_type = 'DOWNVOTE') as cnt_down
from post_score ps
inner join score s on s.id = ps.score_id
where ps.post_id = p.id
) s
order by s.cnt_up - s.cnt_down desc
也许这个数据结构很糟糕,我应该以不同的方式构建我的实体?
就目前而言,我认为不需要两个不同的表 post_score
和 score
。对于您显示的数据,这是一种 1-1 关系,因此只有一张表就足够了,用于存储帖子 ID 和评分类型。
您最好使用 LEFT
联接,否则您不会收到尚未投票的帖子。然后聚合以获得分数的拟合总和。然后将这些总和相加,对没有投票的帖子应用 coalesce()
得到 0
,并按结果排序。
SELECT p.id,p.title
FROM post p
LEFT JOIN post_score ps
ON ps.post_id = p.id
LEFT JOIN score s
ON s.id = ps.score_id
GROUP BY p.id,p.title
ORDER BY coalesce(sum(1) FILTER (WHERE rating_type = 'UPVOTE')
+
sum(-1) FILTER (WHERE rating_type = 'DOWNVOTE'),0);
我同意 GMB 关于多余桌子的评论。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。