【问题标题】:MySQL adding a 4th table to SELECT messes up resultsMySQL 将第 4 个表添加到 SELECT 会弄乱结果
【发布时间】:2021-08-08 07:20:26
【问题描述】:

我从来没有三次加入,而且我的 SQL 很差,而且我搞砸了一些事情。

Tables:

article - 
   id(pk), publicist_id(fk - publicist.id), title, synopsys, text, status ...

publicist - 
   id(pk), name ... + stuff that doesn't matter 

rating - 
   id(pk), article_id(fk - article.id), article_rating 

(and later on) comment - 
   id(pk), author, text, article_id(fk - article.id), status ... 

status 只是一个 tinyInt 来查看它是否处于活动状态。

到目前为止,我一直在使用这个(文章、公关人员、评级):

SELECT article.id, 
article.title, 
article.synopsys, 
publicist.name, 
IFNULL(CAST(AVG(rating.article_rating) AS DECIMAL(10,2)),0) AS avg_rating, 
IFNULL(COUNT(rating.article_rating),0) AS number_of_ratings 
FROM article 
JOIN publicist ON publicist.id = publicist_id 
JOIN rating ON rating.article_id = article.id 
GROUP BY article.id;

这很有效,可以显示标题、概要、名称、平均评分(2 位小数)和文章的评分数。

现在我还必须在每篇文章中包含 cmets 的数量,我无法管理。
这是我尝试过的:

SELECT a.id, 
a.title, 
a.synopsys, 
p.name, 
IFNULL(CAST(AVG(r.article_rating) AS DECIMAL(10,2)),0) AS avg_rating,
IFNULL(COUNT(r.article_rating),0) AS number_of_ratings,
IFNULL(COUNT(CASE WHEN c.status = 1 THEN 1 END),0) AS number_of_comments    -- this is new
FROM article a
JOIN publicist p ON p.id = a.publicist_id
LEFT JOIN rating r ON r.article_id = a.id     -- LEFT JOIN here
LEFT JOIN comment c ON c.article_id = a.id    -- this is new
GROUP BY a.id;

我也尝试只计算状态设置为 1 的 cmets,但这并不重要。 到目前为止,它所做的只是弄乱了我之前版本的评分数字,似乎它在 number_of_ratings 和 number_of_cmets 中都抛出了随机数,

例如:
文章 1 有 7 个评分和 3 个 cmets
article2 有 3 个评级和 3 个 cmets(2 个有效,1 个无效)
文章1:
1st version: number_of_ratings: 7
2nd version: number_of_ratings: 14, comments: 14
文章1:
1st version: number_of_ratings: 3
2nd version: number_of_ratings: 9, comments: 6

我不知道如何解决这个问题,甚至不知道为什么会这样。
另外,我在 COUNT(CASE WHEN c.status = 1 THEN 1 END) 的正确道路上吗?

谢谢!

【问题讨论】:

  • '加入乘法'。计数子查询然后加入。
  • @Akina 谢谢,我不知道加入乘法。 Umberto-petrov 在他的回答中使用了这种方法,而且效果很好。
  • @Strawberry,谢谢,我是新来的,以后会更加注意我的帖子质量。
  • 没有像现在这样的时间。

标签: mysql sql join count


【解决方案1】:

我认为您可以在子查询中计算每篇文章的 cmets,然后加入它:

SELECT article.id, 
article.title, 
article.synopsys, 
publicist.name, 
IFNULL(CAST(AVG(rating.article_rating) AS DECIMAL(10,2)),0) AS avg_rating, 
IFNULL(COUNT(rating.article_rating),0) AS number_of_ratings ,
IFNULL(c.CommentCount,0) AS number_of_comments    --NEW
FROM article 
JOIN publicist ON publicist.id = publicist_id 
JOIN rating ON rating.article_id = article.id 
JOIN (                                            --NEW
  SELECT article_id, COUNT(*) as CommentCount
  FROM comment
  GROUP BY article_id
) c ON article.id = c.article_id
GROUP BY article.id;

【讨论】:

  • 谢谢你,这很好用。将最后 2 个 JOIN 切换为 LEFT JOINS,因此评分/cmets 为 0 的文章也会显示。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-12-17
  • 2014-12-06
  • 1970-01-01
  • 1970-01-01
  • 2017-08-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多