首页 > 解决方案 > SQL中UNION的正确使用

问题描述

我需要计算两个不同评分平均值之间的差异,一个用于在特定 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
);

标签: sqlsqlite

解决方案


您想首先获得每部电影的平均评分。从这个结果中,您想获得 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;

(如前所述,您可能希望在 pre 或 post 范围中包含 1980 年的电影,而不是完全省略它们。)


推荐阅读