方法一,使用join做两表关联

with t as
(
			select a.uid uid1,exam_id,start_time,submit_time,score,
			case when score>=90 then '优'
			when score>=75 then '良'
			when score>=60 then '中'
			 else  '差' 
			end as score_grade,
			`level` 
			from exam_record a
			left join user_info b
			on a.uid=b.uid
			where submit_time is not null
)

select `level1` `level`, score_grade,round(SUM(个数)/SUM(总个数),3) ratio
from 

     
			(select `level` `level1`, score_grade,count(*) 个数
			from t
			group by `level`, score_grade) t1
			inner join
			(

			select `level`,count(*) 总个数
			from t
			group by `level`
			) t2
			on t1.`level1`=t2.`level`

group by `level1`, score_grade
order by `level1` desc,ratio desc
方法二: 使用开窗函数,count,在不改变表结构情况下,计数大小

select level,
    score_grade,
    round(count(*) / avg(total), 3) ratio
from (
    select bb.level,
        case when score >= 90 then '优'
            when score >= 75 then '良'
            when score >= 60 then '中'
            else '差' end score_grade,
        count(aa.uid) over(partition by level) total
    from exam_record aa
    join user_info bb on aa.uid=bb.uid
    where score is not null
) t1
group by level, score_grade
order by level desc, ratio desc
开窗函数复习
rank() over() 1 2 2 4 4 6  (计数排名,跳过相同的几个,eg.没有3没有5)\
row_number() over() 1 2 3 4 5 6 (赋予唯一排名)
dense_rank() over() 1 2 2 3 3 4 (不跳过排名,可以理解为对类别进行计数)
percent_rank() over() 按照数字所在的位置进行百分位分段
ntile(n)over() 将数字按照大小平均分成n段
lead(字段名,n)over()把字段数据向前移n个单元格
lag(字段名,n)over()把字段数据向后移n个单元格
last_value(字段名1) over (order by   rows between unbounded preceding and unbounded following) 根据排序返回字段名1最后一行,也可以加上partition by 一起使用
frist_value(字段名2) over (order by   rows between unbounded preceding and unbounded following) 根据排序返回字段名2第一行,也可以加上partition by 一起使用
5个常用的聚合窗口函数
min()over() :不改变表结构的前提下,计算出最小值
max()over():不改变表结构的前提下,计算出最大值
count()over():不改变表结构的前提下,计数
sum()over():不改变表结构的前提下,求和
avg()over():不改变表结构的前提下,求平均值