如何根据条件删除结果以计算平均和特定电影

Posted

技术标签:

【中文标题】如何根据条件删除结果以计算平均和特定电影【英文标题】:How do I remove results based on conditions to calculate an average and specific movie 【发布时间】:2021-02-26 14:43:06 【问题描述】:

我有下面的架构。一个简单的解释是:

    鲍勃给这部电影评分,5/5 詹姆斯对这部电影的评分提高了 1/5 macy 给这部电影评分,5/5 没有人评价电影复仇者联盟。

逻辑:

    如果我是 personA,请查找我已阻止的所有人。 查看所有电影评论。 任何留下了影评且 personA 已屏蔽的人,将其从计算中移除。 计算电影的平均评分。

CREATE TABLE movies (
  id integer AUTO_INCREMENT primary key,
  name varchar(100) NOT NULL
);

CREATE TABLE customer (
  id integer AUTO_INCREMENT primary key,
  name varchar(100) NOT NULL
);

CREATE TABLE reviews (
  id integer AUTO_INCREMENT primary key,
  rating integer NOT NULL,
  cus_id integer NOT NULL,
  movie_id integer NOT NULL,
  FOREIGN KEY (cus_id) REFERENCES customer(id),
  FOREIGN KEY (movie_id) REFERENCES movies(id)
);

CREATE TABLE blocked(
  id integer AUTO_INCREMENT primary key,
  cus_id integer NOT NULL, -- This is the person blocking
  blocked_cus_id integer NOT NULL, -- This is the person who is blocked
  FOREIGN KEY (cus_id) REFERENCES customer(id),
  FOREIGN KEY (blocked_cus_id) REFERENCES customer(id)
);

INSERT INTO movies (id, name) VALUES (1, 'up'), (2, 'avengers');
INSERT INTO customer (id, name) VALUES (1, 'bob'), (2, 'james'), (3, 'macy');
INSERT INTO reviews (id, rating, cus_id, movie_id) VALUES (1, 5, 1, 1), (2, 1, 2, 1), (3, 5, 3, 1);
INSERT INTO blocked (id, cus_id, blocked_cus_id) VALUES (1, 1, 2);

我在这里收到了一些关于这个问题的帮助:How do I remove results based on conditions to calculate an average(并且该声明是正确的)但是当我想查找特定电影的评级时,该声明仅显示有评级的电影。我希望它显示这部电影,无论它是否有评级。如果它没有评分,它应该只是说 0。下面,电影复仇者没有评分,也没有显示结果。

SELECT m.name, AVG(r.rating) AS avg_rating
FROM movies m
INNER JOIN reviews r ON m.id = r.movie_id
WHERE NOT EXISTS (SELECT 1 FROM blocked b
                  WHERE b.blocked_cus_id = r.cus_id AND b.cus_id = 1)
AND m.id = 2
GROUP BY m.name;

上面的select语句应该显示:

+----------+------------+
| movie    | avg_rating |
+----------+------------+
| avengers |          0 |
+----------+------------+

当我以 bob 形式查看数据库时,我应该得到:

+-------+------------+
| movie | avg_rating |
+-------+------------+
| up    |          5 |
+-------+------------+

当我将数据库视为 macy 时,我应该得到:

+-------+------------+
| movie | avg_rating |
+-------+------------+
| up    |       3.67 |
+-------+------------+

【问题讨论】:

【参考方案1】:

您想要left join 吗?从您当前的查询开始,这将是:

SELECT m.name, AVG(COALESCE(r.rating, 0)) AS avg_rating
FROM movies m
LEFT JOIN reviews r 
    ON m.id = r.movie_id
    AND NOT EXISTS (
        SELECT 1 
        FROM blocked b
        WHERE b.blocked_cus_id = r.cus_id AND b.cus_id = 1
    )
WHERE m.id = 2
GROUP BY m.id, m.name;

【讨论】:

以上是关于如何根据条件删除结果以计算平均和特定电影的主要内容,如果未能解决你的问题,请参考以下文章

如何删除具有特定条件的行? [复制]

如何根据具有特定条件的特定记录的用户权限有效过滤大量记录?

SQL语句对返回的结果集里的字段再进行条件查询,在一个结果集显示

您将如何计算 IMDB 电影评分?

excel怎样用SUMIF来计算平均年龄

如何根据剑道网格中的特定列条件更改行的颜色以获取角度