首页 > 试题广场 >

完成员工考核试卷突出的非领导员工

[编程题]完成员工考核试卷突出的非领导员工
  • 热度指数:21981 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
2021年结束,某公司组织了一场员工年终考核。作答用时少于同类试卷平均值且个人分数大于同类试卷总体平均值的员工记为该类型的突出员工。
有员工信息表 emp_info 如下:
(emp_id员工ID,emp_name员工姓名, emp_level员工等级, register_time入职时间,其中emp level<7的是员工,其他是领导)
考核试卷信息表 examination_info 如下:
(exam_id试卷ID, tag试卷类别, duration考试时长, release_time发布时间)
试卷作答记录表 exam_record 如下:
(emp_id员工ID, exam_id试卷ID, start_time开始作答时间, submit_time交卷时间, score得分):
请你找到作答每类试卷的突出非领导员工,并输出他们的员工ID,员工等级和突出试卷类别并按照员工ID升序排序,若某员工两类试卷都突出,则按照试卷ID升序排序。
由示例数据结果输出如下:

解释:
9001试卷平均得分为78.667分,得分高于78.667且符合员工等级小于7的员工有1005、1007
9001试卷平均作答时间为27.3分钟,作答时间小于27.3分钟且符合员工等级小于7的员工有1006、1007
因此9001号卷突出员工为1007
9002试卷平均得分为75.833分,得分高于75.833且符合员工等级小于7的员工有1005、1006
9002试卷平均作答时间为34.2分钟,作答时间小于34.2分钟且符合员工等级小于7的员工有1006、1007
因此9002号卷突出员工为1006

示例1

输入

drop table if exists emp_info,examination_info,exam_record;
CREATE TABLE emp_info (
  emp_id INT NOT NULL,
  emp_name VARCHAR(45) NOT NULL,
  emp_level INT NOT NULL,
  register_time DATE NOT NULL,
  PRIMARY KEY (emp_id)
);

INSERT INTO emp_info VALUES (1001, '张老板', 10, '2017-10-01');
INSERT INTO emp_info VALUES (1002, '刘主管', 9, '2017-10-01');
INSERT INTO emp_info VALUES (1003, '李主任', 8, '2017-10-23');
INSERT INTO emp_info VALUES (1004, '王组长', 7, '2017-12-23');
INSERT INTO emp_info VALUES (1005, '张三', 4, '2020-01-22');
INSERT INTO emp_info VALUES (1006, '李四', 3, '2021-03-06');
INSERT INTO emp_info VALUES (1007, '王五', 3, '2021-07-04');

CREATE TABLE examination_info (
    exam_id int PRIMARY KEY ,
    tag varchar(32) NOT NULL ,
    duration int NOT NULL ,
    release_time datetime
);

INSERT INTO examination_info VALUES (9001, '企业文化', 60, '2021-12-29');
INSERT INTO examination_info VALUES (9002, '技术水平', 60, '2021-12-29');

CREATE TABLE exam_record (
    emp_id int NOT NULL,
    exam_id int NOT NULL,
    start_time datetime NOT NULL,
    submit_time datetime,
    score tinyint
);

INSERT INTO exam_record VALUES(1002, 9001, '2021-12-30 09:01:01', '2021-12-30 09:21:59', 80);
INSERT INTO exam_record VALUES(1002, 9002, '2021-12-31 09:01:01', '2021-12-31 09:41:42', 74);
INSERT INTO exam_record VALUES(1003, 9001, '2021-12-30 09:01:01', '2021-12-30 09:27:49', 90);
INSERT INTO exam_record VALUES(1003, 9002, '2021-12-31 09:01:01', '2021-12-31 09:37:24', 60);
INSERT INTO exam_record VALUES(1004, 9001, '2021-12-30 09:01:01', '2021-12-30 09:31:59', 60);
INSERT INTO exam_record VALUES(1004, 9002, '2021-12-31 09:01:01', '2021-12-31 09:26:07', 70);
INSERT INTO exam_record VALUES(1005, 9001, '2021-12-30 09:01:01', '2021-12-30 09:42:37', 83);
INSERT INTO exam_record VALUES(1005, 9002, '2021-12-31 09:01:01', '2021-12-31 09:51:43', 92);
INSERT INTO exam_record VALUES(1006, 9001, '2021-12-30 09:01:01', '2021-12-30 09:27:42', 66);
INSERT INTO exam_record VALUES(1006, 9002, '2021-12-31 09:01:01', '2021-12-31 09:32:06', 97);
INSERT INTO exam_record VALUES(1007, 9001, '2021-12-30 09:01:01', '2021-12-30 09:17:36', 93);
INSERT INTO exam_record VALUES(1007, 9002, '2021-12-31 09:01:01', '2021-12-31 09:21:59', 62);

输出

1006|3|技术水平
1007|3|企业文化
刚开始以为可以直接用表连接和子查询做出来 结果整半天都没想起用窗口函数 还是看了ai给得提示才回想起用窗口函数 

select emp_id
,emp_level
,tag
from 
    (
        select b1.emp_id as emp_id
        ,tag 
        ,emp_level
        ,score 得分
        ,avg(score)over(partition by tag) 平均得分
        ,TIMESTAMPDIFF(MINUTE,start_time,submit_time) 答题时长
        ,avg(TIMESTAMPDIFF(MINUTE,start_time,submit_time))over(partition by tag) 平均时长
        from emp_info b1
        join exam_record b2
        on b1.emp_id = b2.emp_id
        and emp_level < 7
        join examination_info b3
        on b2.exam_id = b3.exam_id
    ) a 
where 得分 > 平均得分 and 答题时长 < 平均时长
order by emp_id

发表于 2026-01-21 15:54:48 回复(0)
难点是找出比平均分高,比平均时间短的员工。可以在作答记录表最后加两列平均分和平均时间即可
select
    e.emp_id,
    emp_level,
    tag exam_tag
from
    exam_record e
    left join (
        select
            exam_id,
            avg(score) avg_score,
            avg(
                timestampdiff(second, start_time, submit_time) / 60
            ) avg_time
        from
            exam_record
        group by
            exam_id
    ) t on e.exam_id = t.exam_id
    left join emp_info emp on emp.emp_id = e.emp_id
    left join examination_info exi on exi.exam_id = e.exam_id
where
    emp_level < 7
    and e.score > t.avg_score
    and timestampdiff(second, start_time, submit_time) / 60 < avg_time
发表于 2025-12-30 11:33:14 回复(0)
WITH ag AS (
    select
        *,
        avg(timestampdiff(second,start_time,submit_time)) over(partition by exam_id) as avg_time,
        timestampdiff(second,start_time,submit_time) as time_used,
        avg(score) over(partition by exam_id) as avg_score
    from exam_record
)
select
    a.emp_id,
    a.emp_level,
    b.tag
from
    emp_info a
    join ag c on a.emp_id = c.emp_id
    join examination_info b on c.exam_id = b.exam_id
where
    a.emp_level < 7 and c.time_used < c.avg_time and c.score > c.avg_score
order by
    a.emp_id



发表于 2025-12-15 15:54:14 回复(0)
避免冗余链接和重复计算,性能相比官方精解答案更优
with
    a as (
        select
            emp_id,
            exam_id,
            timestampdiff(second, start_time, submit_time) / 60 as duration,
            score
        from
            exam_record
    ),
    b as (
        select
            exam_id,
            avg(duration) as avg_dur,
            avg(score) as avg_s
        from
            a
        group by
            exam_id
    ),
    c as (
        select
            a.emp_id as emp_id,
            a.exam_id as exam_id
        from
            a
            left join b on a.exam_id = b.exam_id
            where a.duration < b.avg_dur and a.score > b.avg_s
    )
select
    c.emp_id as emp_id,
    e.emp_level as emp_level,
    d.tag as exam_tag
from
    c
    join emp_info e on c.emp_id = e.emp_id
    join examination_info d on c.exam_id = d.exam_id
where
    e.emp_level <7
    order by emp_id,d.exam_id

发表于 2025-11-24 16:21:57 回复(0)
with
    t1 as(
        select
            ei.tag,
            avg(timestampdiff(second,start_time,submit_time)/60) avg_time,
            avg(score) avg_score
        from
            examination_info as ei
            join exam_record as er on ei.exam_id=er.exam_id
        group by
            ei.tag
    )
select
    er.emp_id,
    emp_level,
    ei.tag exam_tag
from
    emp_info as emp
    join exam_record as er on emp.emp_id=er.emp_id
    join examination_info as ei on er.exam_id=ei.exam_id
    join t1 on ei.tag = t1.tag
where
    emp.emp_level < 7
    and timestampdiff(second,start_time,submit_time)/60 < t1.avg_time
    and er.score > t1.avg_score
order by
    er.emp_id,
    er.exam_id 
打卡:2025.11.11.10:59
发表于 2025-11-11 10:59:30 回复(0)
with t1 as (
select x.emp_id,x.emp_level,tag,y.exam_id,
timestampdiff(minute,start_time,submit_time) as time,
avg(timestampdiff(minute,start_time,submit_time)) over(partition by 
tag) as avg_time,
score,
avg(score) over(partition by tag) as avg_score
from emp_info x 
join exam_record y
on x.emp_id=y.emp_id
join examination_info z 
on y.exam_id=z.exam_id
where emp_level<7
)
select emp_id,emp_level,tag as exam_tag
from t1 
where time<avg_time and score>avg_score
order by emp_id,exam_id

发表于 2025-10-16 17:47:46 回复(0)
select a.emp_id,a.emp_level,a.tag from
(   select e.emp_id
    ,e.exam_id
    ,timestampdiff(minute,e.start_time,e.submit_time) time1
    ,e.score
    ,e1.tag
    ,e2.emp_level from exam_record e
    left join examination_info e1 on e.exam_id=e1.exam_id
    left join emp_info e2 on e.emp_id=e2.emp_id ) a
left join
(  select exam_id,avg(timestampdiff(minute,start_time,submit_time)) avg_time,avg(score) avg_score from exam_record
    group by 1
) b on a.exam_id = b.exam_id
where a.time1 < b.avg_time and a.score > b.avg_score
and a.emp_level < 7
发表于 2025-03-28 15:43:19 回复(0)