首页 > 试题广场 >

试卷完成数同比2020年的增长率及排名变化

[编程题]试卷完成数同比2020年的增长率及排名变化
  • 热度指数:63838 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解

现有试卷信息表examination_info(exam_id试卷ID, tag试卷类别, difficulty试卷难度, duration考试时长, release_time发布时间):


试卷作答记录表exam_record(uid用户ID, exam_id试卷ID, start_time开始作答时间, submit_time交卷时间, score得分)

请计算2021年上半年各类试卷的做完次数相比2020年上半年同期的增长率(百分比格式,保留1位小数),以及做完次数排名变化,按增长率和21年排名降序输出。
由示例数据结果输出如下:


解释:2020年上半年有3个tag有作答完成的记录,分别是C++、SQL、PYTHON,它们被做完的次数分别是3、3、2,做完次数排名为1、1(并列)、3
2021年上半年有2个tag有作答完成的记录,分别是算法、SQL,它们被做完的次数分别是3、2,做完次数排名为1、2;具体如下:

因此能输出同比结果的tag只有SQL,从2020到2021年,做完次数3=>2,减少33.3%(保留1位小数);排名1=>2,后退1名。
示例1

输入

drop table if exists examination_info,exam_record;
CREATE TABLE examination_info (
    id int PRIMARY KEY AUTO_INCREMENT COMMENT '自增ID',
    exam_id int UNIQUE NOT NULL COMMENT '试卷ID',
    tag varchar(32) COMMENT '类别标签',
    difficulty varchar(8) COMMENT '难度',
    duration int NOT NULL COMMENT '时长',
    release_time datetime COMMENT '发布时间'
)CHARACTER SET utf8 COLLATE utf8_general_ci;

CREATE TABLE exam_record (
    id int PRIMARY KEY AUTO_INCREMENT COMMENT '自增ID',
    uid int NOT NULL COMMENT '用户ID',
    exam_id int NOT NULL COMMENT '试卷ID',
    start_time datetime NOT NULL COMMENT '开始时间',
    submit_time datetime COMMENT '提交时间',
    score tinyint COMMENT '得分'
)CHARACTER SET utf8 COLLATE utf8_general_ci;

INSERT INTO examination_info(exam_id,tag,difficulty,duration,release_time) VALUES
  (9001, 'SQL', 'hard', 60, '2020-01-01 10:00:00'),
  (9002, 'C++', 'hard', 80, '2020-01-01 10:00:00'),
  (9003, '算法', 'hard', 80, '2020-01-01 10:00:00'),
  (9004, 'PYTHON', 'medium', 70, '2020-01-01 10:00:00');
	
INSERT INTO exam_record(uid,exam_id,start_time,submit_time,score) VALUES
(1001, 9001, '2020-08-02 10:01:01', '2020-08-02 10:31:01', 89),
(1002, 9001, '2020-04-01 18:01:01', '2020-04-01 18:59:02', 90),
(1001, 9001, '2020-04-01 09:01:01', '2020-04-01 09:21:59', 80),
(1002, 9003, '2021-01-20 10:01:01', '2021-01-20 10:10:01', 81),
(1002, 9001, '2021-03-02 19:01:01', '2021-03-02 19:32:00', 20),
(1001, 9003, '2021-04-02 19:01:01', '2021-04-02 19:40:01', 89),
(1004, 9004, '2020-05-02 12:01:01', '2020-05-02 12:20:01', 99),
(1003, 9001, '2021-05-02 12:01:01', '2021-05-02 12:31:01', 98),
(1001, 9002, '2020-02-02 12:01:01', '2020-02-02 12:20:01', 99),
(1002, 9002, '2020-02-02 12:01:01', '2020-02-02 12:43:01', 81),
(1001, 9002, '2020-01-02 19:01:01', '2020-01-02 19:59:01', 69),
(1001, 9004, '2021-09-02 12:11:01', null, null),
(1003, 9001, '2020-01-02 10:01:01', '2020-01-02 10:31:01', 89),
(1002, 9004, '2020-01-01 12:11:01', '2020-01-01 12:31:01', 83),
(1002, 9003, '2021-01-01 18:01:01', '2021-01-01 18:59:02', 90),
(1002, 9002, '2020-02-02 12:01:01', null, null),
(1002, 9002, '2020-03-02 12:11:01', null, null),
(1001, 9002, '2021-05-05 18:01:01', null, null);

输出

SQL|3|2|-33.3%|1|2|1
SELECT tag, exam_cnt_20, exam_cnt_21,
    CONCAT(ROUND((exam_cnt_21 - exam_cnt_20)/exam_cnt_20 * 100, 1), "%") AS growth_rate,
    exam_cnt_rank_20, exam_cnt_rank_21,
    (CAST(exam_cnt_rank_21 AS SIGNED) - CAST(exam_cnt_rank_20 AS SIGNED)) AS exam_cnt_rank
FROM(
    SELECT tag, exam_cnt_20, exam_cnt_21, rank() OVER(ORDER BY exam_cnt_20 DESC) AS exam_cnt_rank_20,
        rank() OVER(ORDER BY exam_cnt_21 DESC) AS exam_cnt_rank_21
    FROM(
        SELECT tag, SUM(IF(YEAR(submit_time) = 2020 AND MONTH(submit_time) <= 6, 1, 0)) AS exam_cnt_20,
            SUM(IF(YEAR(submit_time) = 2021 AND MONTH(submit_time) <= 6, 1, 0)) AS exam_cnt_21
        FROM examination_info a JOIN exam_record USING(exam_id)
        WHERE submit_time IS NOT NULL
        GROUP BY tag
    )t
)t
WHERE exam_cnt_20 > 0 AND exam_cnt_21 > 0
ORDER BY ROUND((exam_cnt_21 - exam_cnt_20)/exam_cnt_20 * 100, 1) DESC, exam_cnt_rank_21 DESC;
发表于 2025-04-01 11:20:35 回复(0)
with t1 as (
    select tag,
    count(if(year(submit_time) = 2020 and month(submit_time) <= 6,1,null)) exam_cnt_20,
    count(if(year(submit_time) = 2021 and month(submit_time) <= 6,1,null)) exam_cnt_21
    from exam_record
    left join examination_info using(exam_id)
    group by tag
),

t2 as (
    select tag,exam_cnt_20,exam_cnt_21,
    rank() over(order by exam_cnt_20 desc) exam_cnt_rank_20,
    rank() over(order by exam_cnt_21 desc) exam_cnt_rank_21
    from t1
)

select tag,exam_cnt_20,exam_cnt_21, growth_rate,exam_cnt_rank_20,exam_cnt_rank_21,rank_delta
from (
    select tag, exam_cnt_20, exam_cnt_21,
    concat(round((exam_cnt_21 - exam_cnt_20) / exam_cnt_20 *100,1), "%") as growth_rate,
    exam_cnt_rank_20,exam_cnt_rank_21,
    cast(exam_cnt_rank_21 as signed) - cast(exam_cnt_rank_20 as signed) as rank_delta
    from t2
) t3
where exam_cnt_20 > 0 and exam_cnt_21 > 0
order by growth_rate desc, exam_cnt_rank_21 desc

发表于 2025-03-25 18:12:00 回复(0)
三步走:(一表examination_info,二表exam_record
1.取出二表中2020和2021上半年的数据,连接到一表上,并统计每个类别的完题数(t1)
2.对每一年的完题数进行排序,并求取增长率(t2)
3.按照题目要求,只保留21年有答题的类别,和增长率不为空的数据,同时计算排名变化(cast函数强转数据类型)
with t1 as(
select tag,
count(if(year(submit_time)=2020,1,null)) exam_cnt_20,
count(if(year(submit_time)=2021,1,null)) exam_cnt_21
from examination_info ei
left join exam_record er
on ei.exam_id=er.exam_id and year(er.start_time) in(2020,2021)
and (month(er.start_time) between 1 and 6)
group by tag
),
t2 as(
select *,
concat(round((exam_cnt_21/exam_cnt_20-1)*100,1),'%') growth_rate,
rank()over(order by exam_cnt_20 desc) exam_cnt_rank_20,
rank()over(order by exam_cnt_21 desc) exam_cnt_rank_21
from t1
)

select tag,exam_cnt_20,exam_cnt_21,growth_rate,exam_cnt_rank_20,exam_cnt_rank_21,
cast(exam_cnt_rank_21 as signed)-cast(exam_cnt_rank_20 as signed) rank_delta
from t2
where exam_cnt_21<>0 and growth_rate is not null
order by growth_rate desc,exam_cnt_rank_21 desc



发表于 2025-03-03 17:55:24 回复(0)
/*计算填写次数、排名*/
with t1 as (select tag,year(start_time) as start_year,count(case when submit_time is not null then er.exam_id end) as exam_cnt,
rank()over(partition by year(start_time) order by count(case when submit_time is not null then er.exam_id end) desc) as exam_cnt_rank
from exam_record as er
left join examination_info as ei
on er.exam_id = ei.exam_id
where month(start_time) between 0 and 6
group by year(start_time),tag
order by year(start_time),exam_cnt desc),
/*计算20、21年试卷*/
t2 as (select a.tag,a.exam_cnt as exam_cnt_20,b.exam_cnt as exam_cnt_21
from
(select tag,exam_cnt
from t1
where start_year = 2020 and exam_cnt>0) as a
join
(select tag,exam_cnt
from t1
where start_year = 2021 and exam_cnt>0) as b
on a.tag = b.tag),
/*计算20、21年试卷填写次数排名*/
t3 as (select a.tag,a.exam_cnt_rank as exam_cnt_rank_20,b.exam_cnt_rank as exam_cnt_rank_21
from
(select tag,exam_cnt_rank
from t1
where start_year = 2020 and exam_cnt_rank is not null ) as a
join
(select tag,exam_cnt_rank
from t1
where start_year = 2021 and exam_cnt_rank is not null) as b
on a.tag = b.tag)

/*合并所有信息*/
select t2.tag,
exam_cnt_20,exam_cnt_21, concat(round(((exam_cnt_21-exam_cnt_20)/exam_cnt_20)*100,1),'%') as growth_rate,
exam_cnt_rank_20,exam_cnt_rank_21,cast(exam_cnt_rank_21 as signed) - cast(exam_cnt_rank_20 as signed)
from t2
join t3
on t2.tag = t3.tag
order by growth_rate desc,exam_cnt_rank_21 desc
发表于 2024-09-02 14:23:26 回复(0)
with tmp as(
    select
        bb.tag,
        sum(if(start_year='2020',1,0)) exam_cnt_20,
        sum(if(start_year='2021',1,0)) exam_cnt_21
    from (
        select
            uid,
            exam_id,
            year(start_time) start_year,
            submit_time
        from exam_record
        where  year(start_time) in ('2020','2021')
        and month(start_time)<=6
    ) aa
    left join (
        select
            exam_id,
            tag
        from examination_info
    ) bb
    on aa.exam_id=bb.exam_id
    where submit_time is not null
    group by 1
)
select
    tag,
    exam_cnt_20,
    exam_cnt_21,
    concat(round((exam_cnt_21-exam_cnt_20)/exam_cnt_20*100,1),'%') growth_rate,
    exam_cnt_rank_20,
    exam_cnt_rank_21,
    cast(exam_cnt_rank_21 as signed)-cast(exam_cnt_rank_20 as signed) rank_delta
from (
    select
        tag,
        exam_cnt_20,
        exam_cnt_21,
        rank() over(order by exam_cnt_20 desc) exam_cnt_rank_20,
        rank() over(order by exam_cnt_21 desc) exam_cnt_rank_21
    from tmp
) tt
where exam_cnt_20!=0 and  exam_cnt_21!=0
order by growth_rate desc,exam_cnt_rank_21 desc
   

发表于 2024-08-19 10:11:57 回复(0)
哎呦喂,又是自测运行通过,提交不行
发表于 2024-07-16 10:34:00 回复(2)
SELECT
    tag
    ,exam_cnt_20
    ,exam_cnt_21
    ,growth_rate
    ,exam_cnt_rank_20
    ,exam_cnt_rank_21
    ,rank_delta
FROM
(
SELECT
    tag
    ,start_year
    ,lag(exam_cnt,1)over(partition by tag order by start_year) as exam_cnt_20
    ,exam_cnt as exam_cnt_21
    ,concat(round((exam_cnt/lag(exam_cnt,1)over(partition by tag order by start_year)-1)*100,1),"%") as growth_rate
    ,lag(exam_cnt_rank,1)over(partition by tag order by start_year) as exam_cnt_rank_20
    ,exam_cnt_rank as exam_cnt_rank_21
    ,cast(exam_cnt_rank AS SIGNED)-cast(lag(exam_cnt_rank,1)over(partition by tag order by start_year)AS SIGNED) as rank_delta
FROM
(
SELECT
    tag
    ,2020 as start_year
    ,count(score) as exam_cnt
    ,rank()over(order by count(score) desc) as exam_cnt_rank
FROM examination_info t1
LEFT JOIN exam_record t2 
ON t1.exam_id = t2.exam_id
WHERE date_format(submit_time,"%Y-%m-%d") between "2020-01-01" and "2020-07-01"
GROUP BY tag,start_year
UNION ALL
SELECT
    tag
    ,2021 as start_year
    ,count(score) as exam_cnt
    ,rank()over(order by count(score) desc) as exam_cnt_rank
FROM examination_info t1
LEFT JOIN exam_record t2 
ON t1.exam_id = t2.exam_id
WHERE date_format(submit_time,"%Y-%m-%d") between "2021-01-01" and "2021-07-01"
GROUP BY tag,start_year
)t1)t2
WHERE start_year = 2021 AND growth_rate is not null
ORDER BY growth_rate desc,rank_delta desc

发表于 2024-07-10 22:50:30 回复(0)
with t as (
    select
        tag,
        count(if(year(submit_time) = 2020 and month(submit_time) <= 6,submit_time,null)) exam_cnt_20,
        count(if(year(submit_time) = 2021 and month(submit_time) <= 6,submit_time,null)) exam_cnt_21,
        rank() over(order by count(if(year(submit_time) = 2020 and month(submit_time) <= 6,submit_time,null)) desc) exam_cnt_rank_20,
        rank() over(order by count(if(year(submit_time) = 2021 and month(submit_time) <= 6,submit_time,null)) desc) exam_cnt_rank_21
    from examination_info ei 
    join exam_record er
    on ei.exam_id = er.exam_id
    group by tag
)
select
    tag,
    exam_cnt_20,
    exam_cnt_21,
    concat(round((exam_cnt_21 - exam_cnt_20) * 100 / exam_cnt_20,1),'%') growth_rate,
    exam_cnt_rank_20,
    exam_cnt_rank_21,
    cast(exam_cnt_rank_21 as signed) - cast(exam_cnt_rank_20 as signed) rank_delta
from t
where exam_cnt_20 != 0 and exam_cnt_21 != 0
order by growth_rate desc,exam_cnt_rank_21 desc;

发表于 2024-06-16 08:51:14 回复(0)
select
     tag
    ,exam_cnt_20
    ,exam_cnt_21
    ,concat(round((exam_cnt_21 - exam_cnt_20)/exam_cnt_20 * 100, 1), '%') as growth_rate
    ,exam_cnt_rank_20
    ,exam_cnt_rank_21
    ,cast(exam_cnt_rank_21 as signed) - cast(exam_cnt_rank_20 as signed) as rank_delta
from (
    select
        t2.tag
        ,sum(if(date_format(t1.start_time, '%Y-%m') between '2020-01' and '2020-06' and t1.submit_time is not null, 1, 0)) as exam_cnt_20
        ,sum(if(date_format(t1.start_time, '%Y-%m') between '2021-01' and '2021-06' and t1.submit_time is not null, 1, 0)) as exam_cnt_21
        ,rank() over(order by sum(if(date_format(t1.start_time, '%Y-%m') between '2020-01' and '2020-06' and t1.submit_time is not null, 1, 0)) desc) as exam_cnt_rank_20
        ,rank() over(order by sum(if(date_format(t1.start_time, '%Y-%m') between '2021-01' and '2021-06' and t1.submit_time is not null, 1, 0)) desc) as exam_cnt_rank_21
    from exam_record as t1
    left join examination_info as t2
        on t1.exam_id = t2.exam_id
    group by
        t2.tag
) as t1
where exam_cnt_20 * exam_cnt_21 != 0
order by
     growth_rate desc
    ,exam_cnt_rank_21 desc
发表于 2024-06-10 12:44:46 回复(0)
select
    c.tag,
    a.exam_cnt_20,
    b.exam_cnt_21,
    concat(round((b.exam_cnt_21-a.exam_cnt_20)/a.exam_cnt_20*100,1),'%') as growth_rate,
    a.exam_cnt_rank_20,
    b.exam_cnt_rank_21,
    cast(b.exam_cnt_rank_21 as signed)-cast(a.exam_cnt_rank_20 as signed) as rank_delta
from    
    (select
        exam_id,
        any_value(year(start_time)) as start_year1,
        count(*) as exam_cnt_20,
        rank() over (order by count(*) desc) as exam_cnt_rank_20
    from
        exam_record
    where
        year(start_time) = 2020
        and month(start_time) <= 6
        and submit_time is not null
    group by
        exam_id) a
    join
    (select
        exam_id,
        any_value(year(start_time)) as start_year2,
        count(*) as exam_cnt_21,
        rank() over (order by count(*) desc) as exam_cnt_rank_21
    from
        exam_record
    where
        year(start_time) = 2021
        and month(start_time) <= 6
        and submit_time is not null
    group by
        exam_id) b
    on a.exam_id = b.exam_id
    join examination_info c
    on a.exam_id = c.exam_id
order by
    growth_rate desc,
    exam_cnt_rank_21 desc
发表于 2024-05-26 15:08:53 回复(0)
SELECT tag, cnt_20 AS exam_cnt_20, cnt_21 AS exam_cnt_21,
       CONCAT(ROUND(100*(cnt_21-cnt_20)/cnt_20 , 1),'%') AS growth_rate,
       rank_20 AS exam_cnt_rank_20, rank_21 AS exam_cnt_rank_21,
       CAST(rank_21 AS signed)-CAST(rank_20 AS signed) AS rank_delta
FROM
(
SELECT tag, year_20, cnt_20,
       RANK() OVER (ORDER BY cnt_20 DESC) AS rank_20
FROM
(
SELECT tag,
       DATE_FORMAT(start_time,'%Y') AS year_20,
       COUNT(IF(submit_time IS NOT NULL,1,NULL)) AS cnt_20
FROM exam_record
LEFT JOIN examination_info USING (exam_id)
WHERE start_time BETWEEN '2020-01-01' AND '2020-06-30'
GROUP BY tag, year_20
) a
ORDER BY year_20,rank_20
) b

LEFT JOIN

(
SELECT tag, year_21, cnt_21,
       RANK() OVER (ORDER BY cnt_21 DESC) AS rank_21
FROM
(
SELECT tag,
       DATE_FORMAT(start_time,'%Y') AS year_21,
       COUNT(IF(submit_time IS NOT NULL,1,NULL)) AS cnt_21
FROM exam_record
LEFT JOIN examination_info USING (exam_id)
WHERE start_time BETWEEN '2021-01-01' AND '2021-06-30'
GROUP BY tag, year_21
) c
ORDER BY year_21,rank_21
) d
USING (tag)
WHERE cnt_21*cnt_20 <> 0
ORDER BY growth_rate DESC, exam_cnt_rank_21 DESC
发表于 2024-05-21 21:10:20 回复(1)
with t1 as(
select tag, '2020' year, count(score) 2020_count, rank()over(order by count(score) desc) rk1
from exam_record left join examination_info using(exam_id)
where year(start_time)=2020 and month(start_time)<=6
group by tag
)
,t2 as(
select tag, '2021' year, count(score) 2021_count, rank()over(order by count(score) desc) rk2
from exam_record left join examination_info using(exam_id)
where year(start_time)=2021 and month(start_time)<=6
group by tag
)
select tag, 2020_count, 2021_count, concat(round(((2021_count-2020_count)/2020_count)*100,1),"%") growth_rate, rk1, rk2, cast(rk2 as signed)-cast(rk1 as signed) rk_delta
from t1 join t2 using(tag)
where 2021_count!=0 and 2020_count!=0
order by growth_rate desc,rk_delta desc
发表于 2024-05-04 12:06:46 回复(0)
select t1.tag
    ,exam_cnt_2020
    ,exam_cnt_2021
    ,concat(round((exam_cnt_2021-exam_cnt_2020)/exam_cnt_2020*100,1),'%') as growth_rate
    ,exam_cnt_rank_20
    ,exam_cnt_rank_21
    ,if(exam_cnt_rank_21>=exam_cnt_rank_20,exam_cnt_rank_21-exam_cnt_rank_20,-(exam_cnt_rank_20-exam_cnt_rank_21)) as rank_delta
from 
    (   select tag,count(tag) as exam_cnt_2021
              ,rank()over(order by count(tag) desc ) as exam_cnt_rank_21
        from exam_record as r 
        join examination_info as e 
        on r.exam_id=e.exam_id
        where score is not null and date_format(start_time,'%Y-%m')<='2021-06'
        and date_format(start_time,'%Y-%m')>='2021-01'
        group by tag 
    ) t1 
join 
    (
        select tag,count(tag) as exam_cnt_2020
            ,rank()over(order by count(tag) desc) as exam_cnt_rank_20
        from exam_record as r 
        join examination_info as e 
        on r.exam_id=e.exam_id
        where score is not null and date_format(start_time,'%Y-%m')<='2020-06'
        and date_format(start_time,'%Y-%m')>='2020-01'
        group by tag    
    ) t2 
on t1.tag=t2.tag
order by growth_rate desc,exam_cnt_rank_21 desc



发表于 2024-04-07 16:41:04 回复(0)
##1.计算2020年和2021上半年tag,exam_cnt_20,exam_cnt_rank_20
with t1 as (
    SELECT *,rank() over ( order by exam_cnt_20 DESC) as exam_cnt_rank_20
    from (
SELECT tag,count(score) as exam_cnt_20
FROM exam_record JOIN examination_info using(exam_id)
WHERE DATE_FORMAT(submit_time,'%Y%m%d') between '20200101' and '20200631'
group by tag) table1
inner join 
(
 SELECT *,rank() over (order by exam_cnt_21 DESC) as exam_cnt_rank_21
    from (
SELECT tag,count(score) as exam_cnt_21
FROM exam_record JOIN examination_info using(exam_id)
WHERE DATE_FORMAT(submit_time,'%Y%m%d') between '20210101' and '20210631'
group by tag) table2) table3 using(tag)
)
SELECT tag,exam_cnt_20,exam_cnt_21,
concat(round(100*(cast(exam_cnt_21 as signed) - cast(exam_cnt_20 as signed))/cast(exam_cnt_20 as signed),1),'%')  as growth_rate,
exam_cnt_rank_20,exam_cnt_rank_21,(cast(exam_cnt_rank_21 as signed) -cast(exam_cnt_rank_20 as signed)) as rank_delta
FROM t1
order by growth_rate DESC,exam_cnt_rank_21 DESC;

不知道为什么 这样算总是排名和正确答案对不上?
图片说明

发表于 2024-03-24 17:07:53 回复(0)
一小时一道题
select tag,
    exam_cnt_20,
    exam_cnt_21,
    concat(round((exam_cnt_21/exam_cnt_20 - 1) * 100, 1), '%') growth_rate,
    exam_cnt_rank_20,
    exam_cnt_rank_21,
    exam_cnt_rank_21 - exam_cnt_rank_20 rank_delta
from(
    select tag,
        sum(case when start_year = 2020 then exam_cnt else null end) exam_cnt_20,
        sum(case when start_year = 2021 then exam_cnt else null end) exam_cnt_21,
        sum(case when start_year = 2020 then exam_cnt_rank else null end)exam_cnt_rank_20,
        sum(case when start_year = 2021 then exam_cnt_rank else null end)exam_cnt_rank_21
    from(
        select tag,
            start_year,
            exam_cnt,
            rank() over(partition by start_year order by exam_cnt desc) as exam_cnt_rank
        from(
            select tag,
                start_year,
                count(distinct id) exam_cnt
            from(
                select er.id, 
                    ei.tag,
                    year(er.submit_time)  start_year
                from examination_info ei right join exam_record er 
                    on ei.exam_id = er.exam_id
                where er.submit_time is not null
                    and month(submit_time) <= 6
                ) e1
            group by tag, start_year
        ) e2
    ) e3
    group by tag
) e4
where exam_cnt_20 is not null 
    and exam_cnt_21 is not null
order by growth_rate desc,
    exam_cnt_rank_21 desc


编辑于 2024-03-21 11:39:11 回复(0)
SELECT
    tag,
    MAX(IF(year = 2020, exam_cnt, 0)) AS exam_cnt_20,
    MAX(IF(year = 2021, exam_cnt, 0)) AS exam_cnt_21,
    CONCAT(
        ROUND((MAX(IF(year = 2021, exam_cnt, 0)) - MAX(IF(year = 2020, exam_cnt, 0))) / MAX(IF(year = 2020, exam_cnt, 0)) * 100, 1), '%'
    ) AS growth_rate,
    MAX(IF(year = 2020, exam_cnt_rank, 0)) AS exam_cnt_rank_20,
    MAX(IF(year = 2021, exam_cnt_rank, 0)) AS exam_cnt_rank_21,
    MAX(IF(year = 2021, exam_cnt_rank, 0)) - MAX(IF(year = 2020, exam_cnt_rank, 0)) AS rank_delta
FROM
    (
        SELECT
            tag,
            YEAR(submit_time) AS year,
            COUNT(*) AS exam_cnt,
            RANK() OVER (PARTITION BY YEAR(submit_time) ORDER BY COUNT(*) DESC) AS exam_cnt_rank
        FROM
            exam_record
            LEFT JOIN examination_info USING (exam_id)
        WHERE
            MONTH(submit_time) <= 6
        GROUP BY
            tag, YEAR(submit_time)
    ) t
GROUP BY
    tag
HAVING
    COUNT(DISTINCT year) = 2
ORDER BY
    growth_rate DESC, exam_cnt_rank_21 DESC

编辑于 2024-03-20 15:29:26 回复(0)
select
    tmp1.tag,
    exam_cnt_20,
    exam_cnt_21,
    concat(round((exam_cnt_21-exam_cnt_20)/exam_cnt_20*100,1),'%') as growth_rate,
    exam_cnt_rank_20,
    exam_cnt_rank_21,
    exam_cnt_rank_21-exam_cnt_rank_20 as rank_delta
from (
-- 2020上半年完成数和排名
select
    t2.tag as tag,
    count(t1.score) as exam_cnt_20,
    cast(rank() over (order by count(t1.score) desc) as signed) as exam_cnt_rank_20
from exam_record as t1
left join examination_info as t2
    on t1.exam_id = t2.exam_id
where date_format(t1.start_time, '%Y-%m') between '2020-01' and '2020-06'
group by t2.tag
having count(t1.score)<>0
) as tmp1
-- 用inner join,需要该tag在两个时段之内都要有作答数据
join (
-- 2021上半年的完成数和排名
select
    t2.tag as tag,
    count(t1.score) as exam_cnt_21,
    cast(rank() over (order by count(t1.score) desc) as signed) as exam_cnt_rank_21
from exam_record as t1
left join examination_info as t2
    on t1.exam_id = t2.exam_id
where date_format(t1.start_time, '%Y-%m') between '2021-01' and '2021-06'
group by t2.tag
having count(t1.score)<>0
) as tmp2
    on tmp1.tag = tmp2.tag
order by growth_rate desc, exam_cnt_rank_21 desc;

发表于 2023-11-18 16:21:14 回复(0)
with t1 as
(select tag,year(submit_time) year2,month(submit_time) month2
from exam_record e1
left join examination_info e2
on e1.exam_id=e2.exam_id)

select 
a.tag,
exam_cnt_20,
exam_cnt_21,
concat(round(((exam_cnt_21-exam_cnt_20)/exam_cnt_20)*100,1),'%') growth_rate,exam_cnt_rank_20,
exam_cnt_rank_21,
cast(exam_cnt_rank_21 as signed)-cast(exam_cnt_rank_20 as signed) rank_delta
from
(select tag,year2 year1,count(year2) exam_cnt_21,rank()over(order by count(year2) desc) exam_cnt_rank_21
from t1
where year2=2021 and month2<=6
group by tag) a
join 
(select tag,year2 year2,count(year2) exam_cnt_20,rank()over(order by count(year2) desc) exam_cnt_rank_20
from t1
where year2=2020 and month2<=6
group by tag) b
on a.tag=b.tag
order by growth_rate desc,exam_cnt_rank_21 desc
因为会反复用到字段是tag,year(submit_time),month(submit_time),所以先把两个原始表连接起来取出这几个字段得到一个新的表t1
with t1 as
(select tag,year(submit_time) year2,month(submit_time) month2
from exam_record e1
left join examination_info e2
on e1.exam_id=e2.exam_id)
然后事情就变简单了,分别取出2020年上半年和2021年上半年的各个tag的完成数和完成排名并将两个表连接起来
(select tag,year2 year1,count(year2) exam_cnt_21,rank()over(order by count(year2) desc) exam_cnt_rank_21
from t1
where year2=2021 and month2<=6
group by tag) a
join
(select tag,year2 year2,count(year2) exam_cnt_20,rank()over(order by count(year2) desc) exam_cnt_rank_20
from t1
where year2=2020 and month2<=6
group by tag) b
on a.tag=b.tag
最后从这个表里面取最终的数据,在cast这个地方卡了,百度了一下报错原因rank出来的值是无字符值,需要用cast转换成数值才能进行计算,解决完成
select
a.tag,
exam_cnt_20,
exam_cnt_21,
concat(round(((exam_cnt_21-exam_cnt_20)/exam_cnt_20)*100,1),'%') growth_rate,exam_cnt_rank_20,
exam_cnt_rank_21,
cast(exam_cnt_rank_21 as signed)-cast(exam_cnt_rank_20 as signed) rank_delta

发表于 2023-11-09 17:27:50 回复(0)