我需要计算两个不同评级平均值之间的差异,一个用于特定year_cutoff(1980)之前的电影评级,另一个用于year_cutoff之后的第二个,从两个不同的数据库查询,评级和电影。
我做的是:
我需要计算1980年以前和1980年后电影之间的平均星数差异。
首先我通过电影标题进行分组并计算每个组的平均评分。
其次,我将这些群体分为两类,1980年之前和1980年之后
最后,我试图重新计算这两组中每一组的平均值(平均值),即avgBefore和avgAfter,并计算这两个新平均值的差异
我希望有一个数字是avgBefore - avgAfter(avgB - avgA)
以下是我对代码的尝试。我的主要问题是在'之前正确插入两个条件。和'之后' 1980.我正在尝试定义像avgB和avgA这样的别名,但显然没有正确调用UNION子句。
SELECT AVG(avgB) - AVG(avgA)
FROM(
SELECT AVG(stars) as avgB
FROM Rating
JOIN Movie
ON Rating.mID = Movie.mID
GROUP BY title
HAVING year < 1980
UNION
SELECT AVG(stars) as avgA
FROM Rating
JOIN Movie
ON Rating.mID = Movie.mID
GROUP BY title
HAVING year > 1980
);
答案 0 :(得分:1)
您希望首先获得每部电影的平均评分。从这个结果你想得到1980年以前和1980年后的平均电影评级。因此,两个步骤:每部电影聚合,然后是总聚合。
select
avg(r.stars) as total,
avg(case when m.year < 1980 then r.stars end) as pre1980,
avg(case when m.year > 1980 then r.stars end) as post1980,
avg(case when m.year < 1980 then r.stars end) -
avg(case when m.year > 1980 then r.stars end) as diff
from
(
select mid, avg(stars) as stars
from rating
group by mid
) r
join movie m on m.mid = r.mid;
(如前所述,您可能希望在前置或后置范围内包含1980部电影,而不是完整地省略它们。)
答案 1 :(得分:0)
试试这个:
SELECT AVG(avgB) - AVG(avgA)
FROM(
SELECT AVG(stars) as avgB
FROM Rating
JOIN Movie
ON Rating.mID = Movie.mID
WHERE Movie.year < 1980
GROUP BY title
UNION
SELECT AVG(stars) as avgA
FROM Rating
JOIN Movie
ON Rating.mID = Movie.mID
WHERE Movie.year >= 1980
GROUP BY title
);
注意:我不知道您从哪里获得year
值,因此您需要指定它。
更新:修正了对year
的引用。
更新2 :更正了查询。
这就是我的想法。请注意,我现在无权访问数据库来验证语法,但我想它应该主要是确定:
SELECT (AVG(B.Rating_OLD) - AVG(B.Rating_NEW)) AS Rating_Diff
FROM (
SELECT A.title , AVG(A.stars_OLD) AS Rating_OLD ,AVG(A.stars_NEW) AS Rating_NEW
FROM (
SELECT title ,
CASE
WHEN Movie.year < 1980 THEN Rating.stars
ELSE 0
END AS stars_OLD ,
CASE
WHEN Movie.year >= 1980 THEN Rating.stars
ELSE 0
END AS stars_NEW
FROM Rating
JOIN Movie
ON Rating.mID = Movie.mID
) A
GROUP BY A.title
) B
答案 2 :(得分:0)
如果我们遵循这种方法会怎样:
SELECT
(AVG(CASE WHEN year < 1980 THEN stars ELSE 0 END)-
AVG(CASE WHEN year >= 1980 THEN stars ELSE 0 END)) AS averag
FROM Rating
JOIN Movie ON Rating.mID = Movie.mID
答案 3 :(得分:0)
在UNION上使用连接:
SELECT
AVG(avgB) - AVG(avgA)
FROM
(
(
SELECT
AVG(stars) as avgB
FROM
Rating
JOIN
Movie
ON
Rating.mID = Movie.mID
WHERE
year < 1980
) t1
CROSS JOIN
(
SELECT
AVG(stars) as avgA
FROM
Rating
JOIN
Movie
ON
Rating.mID = Movie.mID
WHERE
year < 1980
) t2
);
答案 4 :(得分:0)
你做错了。在UNION中不能有两个不同的别名。您的脚本只知道别名avgB。 而不是UNION我建议您使用JOIN。
答案 5 :(得分:0)
最有效的方法是使用条件聚合:
SELECT (AVG(CASE WHEN m.year < 1980 THEN r.stars END) -
AVG(CASE WHEN m.year >= 1980 THEN r.stars END)
) AS averag
FROM Rating r JOIN
Movie m
ON r.mID = m.mID;
尝试使用两个单独的查询只会使查询变得比它需要的更复杂。