即使在where函数中实现也无法过滤null

问题描述 投票:0回答:2

三个表:-Rating(rID,mID,stars,ratingDate)电影(mID,标题,年份,导演)评论者(rID,姓名)

找出1980年以前发行的电影的平均评分与1980年以后发行的电影的平均评分之间的差异。

(确保计算每部电影的平均评分,然后计算1980年之前电影和电影之后平均电影的平均值。不要只计算1980年之前和之后的整体平均评分。)

但总有一个空,即使我在函数中过滤了null

''''
select r.mID,sum(stars),
count(case when year>1980 and stars is not null then stars end )as "numaf",
count(case when year<1980 and stars is not null then stars end )as "numbf",
sum(case when year>1980 and stars is not null then stars end )as "sumaf",
sum(case when year<1980 and stars is not null then stars end )as "sumbf",
(("sumaf"/"numaf")-("sumbf"/"numbf")) as "difof"
from Rating r left join movie m on r.mID = m.mID 
where stars is not null
group by r.mID
''''

and this is output, always has "NULL":
101 9   0   3   <NULL>  9   <NULL>
103 5   0   2   <NULL>  5   <NULL>
104 5   2   0   5   <NULL>  <NULL>
106 9   0   2   <NULL>  9   <NULL>
107 8   2   0   8   <NULL>  <NULL>
108 10  3   0   10  <NULL>  <NULL>
sql sqlite syntax-error
2个回答
1
投票

电影的平均评分为:

select r.mID, avg(stars) as avg_stars
from Rating r 
group by r.mID;

然后,要回答这个问题,您可以将其加入电影并使用条件聚合:

select avg(case when year < 1980 then avg_stars) as avg_stars_pre1980,
       avg(case when year > 1980 then avg_stars) as avg_stars_post1980,
       (avg(case when year < 1980 then avg_stars) -
        avg(case when year > 1980 then avg_stars) a
       ) as diff       
from (select r.mID, avg(stars) as avg_stars
      from Rating r 
      group by r.mID
     ) r join
     movie m
     on r.mID = m.mID 
group by r.mID;

你得到NULL的原因是因为你认为你正在划分SELECT中定义的列别名。但是,你真的在​​划分字符串。所以:

(("sumaf"/"numaf")-("sumbf"/"numbf")) as "difof"

仅仅是:

(('sumaf'/'numaf')-('sumbf'/'numbf')) as difof

字符串在数字常量中被解释为数字,前导数字转换为数字。它们没有前导数字,因此值都是0 - 导致除以零。 MySQL返回NULL除以零而不是生成错误。


1
投票

要获得1980年之前和之后分割出的电影的平均评分,您可以执行以下操作:

SELECT SUM(avgRating)/Count(mID), yearSection
FROM (
    SELECT 
       r.mid,
       round(sum(stars),2)/count(r.mID) as avgRating,
       case when year > 1980 then 1 else 0 end as yearSection
from Rating r left join movie m on r.mID = m.mID 
where stars is not null
group by r.mID
     )AS foo
GROUP BY yearSection

这不会导致任何空值。此外,您应该将总和舍入为小数,否则您的平均值将不正确。

© www.soinside.com 2019 - 2024. All rights reserved.