标记
- 标记找规律
- 连续登录2-7天用户
- 建表
- 排名找规律
- 最大连胜次数
- 建表
- 多次排名 找规律
- 输出更多数据
- 标记计数 百分比
标记找规律
连续登录2-7天用户
建表
create table continuous_login(
user_id1 integer comment '用户id',
date_login date comment '登陆日期'
) comment '用户登录表';
insert into continuous_login
values
(1,'2022-01-10'),
(1,'2022-01-11'),
(1,'2022-01-13'),
(1,'2022-01-14'),
(1,'2022-01-15'),
(1,'2022-01-16'),
(1,'2022-01-17'),
(1,'2022-01-18'),
(1,'2022-01-19'),
(2,'2022-01-05'),
(2,'2022-01-06'),
(2,'2022-01-07'),
(2,'2022-01-11'),
(3,'2022-01-01'),
(3,'2022-01-03'),
(3,'2022-01-11');
排名找规律
with tmp as(-- 过滤 保证无重复日期
select *
from continuous_login
group by user_id1,date_login
),
tmp1 as(-- 日期排名 等差数列
select
*,
dense_rank() over(partition by user_id1 order by date_login) dr
from continuous_login
),
tmp2 as(-- 等差 - 等差 = 差一样
select
user_id1,
count(1) days_login_consecutive, -- 连续登录天数
concat(min(date_login),'/',max(date_login)) date_finish_begin -- 拼接 连续登录起止日期
from tmp1
group by user_id1, adddate(date_login,-dr) -- 连续登录日期 等差数列
having count(1) between 2 and 7 -- 连续登录所有情况中过滤出连续登录2-7天
)
select -- 输出格式
user_id1,
group_concat(days_login_consecutive) days_login_consecutive,
group_concat(date_finish_begin) date_finish_begin
from tmp2
group by user_id1;
最大连胜次数
建表
create table if not exists match1(
player_id integer unsigned not null default 0 comment '玩家ID',
match_day date default '1970-01-01' comment '比赛日期',
result1 varchar(5) comment '比赛结果'
) comment '玩家比赛表';
insert into match1
value
('1','2022-01-17','Win'),
('1','2022-01-18','Win'),
('1','2022-01-25','Win'),
('1','2022-01-31','Draw'),
('1','2022-02-08','Win'),
('2','2022-02-06','lose'),
('2','2022-02-08','lose'),
('3','2022-03-30','Win');
多次排名 找规律
with tmp as(-- 日期多次排名 找规律
select
player_id,match_day,result1,
if(result1 = 'Win',1,0) result1_if, -- if标记 为了计数
dense_rank() over(partition by player_id order by match_day) dr,
dense_rank() over(partition by player_id,result1 order by match_day) dr1
from match1
),
tmp1 as(-- 连续同种结果 差一样
select
player_id,
sum(result1_if) consecutive_count
from tmp
group by player_id,dr - dr1
)
select -- 输出格式
player_id,
'Win' result1, -- 比赛结果
max(consecutive_count) max_consecutive_count -- 最大连胜次数
from tmp1
group by player_id;
输出更多数据
with tmp as(-- 日期多次排名 找规律
select
player_id,match_day,result1,
dense_rank() over(partition by player_id order by match_day) dr,
dense_rank() over(partition by player_id,result1 order by match_day) dr1
from match1
)
select -- 连续同种结果 差一样
player_id,
any_value(result1) result1, -- 比赛结果
count(result1) consecutive_count -- 同种结果 连续次数
from tmp
group by player_id,dr - dr1;
标记计数 百分比
各科各分数段人数及百分比,及格为:>=60,中等为:70-80,优良为:80-90,优秀为:>=90
with tmp as(-- 标记score 方便计数
select
c_id,count(1) num,
sum(if(score >= 60,1,0)) pass,
sum(if(score >= 70 and score < 80,1,0)) medium,
sum(if(score >= 80 and score < 90,1,0)) good,
sum(if(score >= 90,1,0)) excellent
from score
group by c_id
)
select -- 百分比
c_id,
num, -- 各科人数
pass, -- 及格人数
if(pass = 0,0,concat(cast(pass / num * 100 as decimal(5,2)),'%')) pass_percent, -- 及格率
medium, -- 中等人数
if(medium = 0,0,concat(cast(medium / num * 100 as decimal(5,2)),'%')) medium_percent, -- 中等率
good, -- 优良人数
if(good = 0,0,concat(cast(good / num * 100 as decimal(5,2)),'%')) good_percent, -- 优良率
excellent, -- 优秀人数
if(excellent = 0,0,concat(cast(excellent / num * 100 as decimal(5,2)),'%')) excellent_percent -- 优秀率
from tmp;