用了个很笨的方法 union all

select user_grade,round(count(uid)/(SELECT COUNT(DISTINCT uid) FROM tb_user_log),2)  radio
from
(-- 忠实用户(近7天活跃过且非新晋用户)
select distinct uid,date(in_time) dt,
case when datediff( (select max(in_time) from tb_user_log),date(in_time))<7 then '忠实用户' end user_grade
from tb_user_log
having user_grade is not null
and uid in
(select uid
from tb_user_log
group by uid
having min(date(in_time)) <(select date_sub(max(in_time),interval 7 day) from tb_user_log))

union all
-- 新晋用户(近7天新增)
--    选出登陆时间在7天内的用户
select distinct uid,min(date(in_time)) mindt, '新晋用户' user_grade
from tb_user_log
group by uid
having datediff( (select max(in_time) from tb_user_log),date(mindt))<7

union all
-- 沉睡用户(近7天未活跃但更早前活跃过)
select distinct uid,date(in_time) dt,'沉睡用户' user_grade
from tb_user_log
where uid not in 
(select uid
from(select uid,date(in_time) dt,
case when datediff( (select max(in_time) from tb_user_log),date(in_time))<7 then '近七天登录用户' end user_grade
from tb_user_log
having user_grade is not null)a)
having datediff( (select max(in_time) from tb_user_log),dt)<30

union all
-- 流失用户(近30天未活跃但更早前活跃过)
select distinct uid,date(in_time) dt,'流失用户' user_grade
from tb_user_log
where uid not in 
(select uid
from(select uid,date(in_time) dt,
case when datediff( (select max(in_time) from tb_user_log),date(in_time))<7 then '近七天登录用户' end user_grade
from tb_user_log
having user_grade is not null)a)
having datediff( (select max(in_time) from tb_user_log),dt)>=30)a
group by user_grade
order by radio desc