首页 > 试题广场 >

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

[编程题]完成员工考核试卷突出的非领导员工
  • 热度指数: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|企业文化
这种题目都一个套路,先看有没有额外的表产生,然后再看限制条件是不是可以用where处理,想明白了无脑join原始表+生成表,然后where 处理就出结果,不用写很多cte

-- 处理非领导的人
SELECT ei.emp_id,
       ei.emp_level,
       exi.tag
FROM emp_info ei
JOIN exam_record er ON ei.emp_id = er.emp_id
JOIN examination_info exi ON er.exam_id = exi.exam_id
JOIN (
    SELECT exam_id,
           AVG(TIMESTAMPDIFF(MINUTE, start_time, submit_time)) AS avg_diff_time,
           AVG(score) AS avg_score
    FROM exam_record
    GROUP BY exam_id
) ae ON er.exam_id = ae.exam_id
WHERE ei.emp_level < 7
  AND er.score > ae.avg_score
  AND TIMESTAMPDIFF(MINUTE, er.start_time, er.submit_time) < ae.avg_diff_time;

发表于 2025-05-28 17:05:13 回复(4)
不是.......这题目有问题吧,哪里说了等级要求了........?
发表于 2025-01-30 16:53:40 回复(5)
SELECT e1.emp_id, e2.emp_level, e3.tag
FROM exam_record e1
JOIN emp_info e2 USING (emp_id)
JOIN examination_info e3 USING (exam_id)
WHERE score > (SELECT AVG(score)
               FROM exam_record
               WHERE exam_id = e1.exam_id)
AND TIMESTAMPDIFF(SECOND, start_time, submit_time) < 
              (SELECT AVG(TIMESTAMPDIFF(SECOND, start_time, submit_time))
              FROM exam_record
              WHERE exam_id = e1.exam_id)
AND e2.emp_level < 7
ORDER BY e1.emp_id, e1.exam_id


发表于 2025-02-11 13:32:59 回复(0)
with a1 as(
select emp_id,exam_id,timestampdiff(minute,start_time,submit_time)/60 as time,
avg(timestampdiff(minute,start_time,submit_time)/60) over(partition by exam_id) as avg_time,
score,
avg(score) over(partition by emp_id) as pavg_score,
avg(score) over(partition by exam_id) as avg_score
from exam_record
order by exam_id,emp_id)

select a1.emp_id,emp_level,tag as exam_tag
from a1
left join examination_info ex on ex.exam_id = a1.exam_id
left join emp_info ei on a1.emp_id=ei.emp_id
where time < avg_time and score > avg_score and emp_level < 7
order by a1.emp_id,a1.exam_id

发表于 2025-01-29 19:53:10 回复(2)
很简单的一题,可以认为是窗口函数例题。

with t1 as (
    select er.*,
    e.emp_name, e.emp_level, e.register_time,
    exam.tag as exam_tag, exam.duration, exam.release_time,
    timestampdiff(second, er.start_time, er.submit_time) as take_time,
    avg(score) over(partition by exam.exam_id) as avg_score,
    avg(timestampdiff(second, er.start_time, er.submit_time)) over(partition by exam.exam_id) as avg_take_time
    from  exam_record er
    join examination_info exam
    on exam.exam_id=er.exam_id
    join emp_info e
    on e.emp_id=er.emp_id
)

select emp_id, emp_level,  exam_tag
from t1
where score>avg_score
and take_time<avg_take_time
and emp_level<7
order by emp_id asc



发表于 2025-04-15 15:09:54 回复(0)
select
    emp.emp_id as exam_id,
    emp.emp_level as emp_level,
    ei.tag as exam_tag
from
    emp_info emp
    left join exam_record er on emp.emp_id = er.emp_id
    left join examination_info ei on ei.exam_id = er.exam_id
    left join (
        select
            re.exam_id exam_id,
            avg(score) avg_score,
            avg(submit_time - start_time) avg_time
        from
            exam_record re
        group by
            re.exam_id
        order by
            re.exam_id
    ) a on a.exam_id = er.exam_id
where
    emp.emp_level < 7
    and er.score > a.avg_score
    and (er.submit_time - er.start_time) < a.avg_time

发表于 2026-02-06 17:13:00 回复(0)
SELECT emp_id,emp_level,exam_tag
FROM (
    SELECT
        e2.exam_id,
        AVG(TIMESTAMPDIFF(SECOND,start_time,submit_time)) avg_time,
        AVG(score) avg_score
    FROM emp_info e1
    JOIN exam_record e3 ON e1.emp_id=e3.emp_id AND emp_level<7
    JOIN examination_info e2 ON e2.exam_id=e3.exam_id
    GROUP BY e2.exam_id
) t1
JOIN (
    SELECT
        e1.emp_id,e1.emp_level,tag AS exam_tag,score,e2.exam_id,
        TIMESTAMPDIFF(SECOND,start_time,submit_time) diff_time
    FROM emp_info e1
    JOIN exam_record e3 ON e1.emp_id=e3.emp_id AND emp_level<7
    JOIN examination_info e2 ON e2.exam_id=e3.exam_id
) t2 ON t1.exam_id=t2.exam_id
WHERE
    diff_time < avg_time
    AND score>avg_score
发表于 2025-10-04 15:31:35 回复(0)
select t1.emp_id,
        emp_level,
       tag as exam_tag
from (select emp_id,
             exam_id,
             score,
             submit_time,
             start_time,
             AVG(score) over (partition by exam_id) as avg,
             AVG(timestampdiff(second,start_time,submit_time)) over (partition by exam_id) as avg_time
      from exam_record er) t1
left join examination_info ei on t1.exam_id=ei.exam_id
left join emp_info empi on empi.emp_id=t1.emp_id
where score > avg and timestampdiff(second,start_time,submit_time) < avg_time and emp_level < 7
order by emp_id,ei.exam_id
发表于 2025-05-01 20:59:14 回复(0)
请问大佬们,MySQL有没有能够直接筛选出score > AVG(score)的函数,这样就不用先专门用一个SELECT获取平均分,再用外层的SELECT去筛选了。
发表于 2025-04-10 15:20:53 回复(2)
with a as (
    select exam_id,avg(submit_time-start_time) at,avg(score) ass
    from exam_record 
    group by exam_id
)
select e.emp_id,ei.emp_level,ex.tag exam_tag
from exam_record  e 
join emp_info  ei 
on e.emp_id=ei.emp_id
join examination_info ex
on e.exam_id=ex.exam_id
join a 
on a.exam_id=e.exam_id
where e.score>a.ass and e.submit_time-e.start_time<at and ei.emp_level<7;

发表于 2025-03-13 17:47:30 回复(0)
SELECT e_i.emp_id, emp_level, tag FROM
    (SELECT er.emp_id, er.exam_id, er.score, e_a_s.a_s, e_a_s.a_t FROM exam_record er join
        (SELECT exam_id, avg(score) a_s, tag, avg(a_t) as a_t FROM
            (SELECT ei.emp_id, emi.exam_id, ei.emp_level, er.score, emi.tag, timestampdiff(second, start_time, submit_time)/60 a_t FROM
                    (SELECT emp_id, emp_level FROM emp_info)ei
                    join exam_record er on ei.emp_id = er.emp_id
                    join examination_info emi on er.exam_id = emi.exam_id) es
        GROUP BY tag, exam_id) e_a_s
    on er.exam_id = e_a_s.exam_id
    WHERE timestampdiff(second, start_time, submit_time)/60 < e_a_s.a_t AND score > e_a_s.a_s AND er.emp_id in (SELECT emp_id FROM emp_info WHERE emp_level < 7))e_i
join emp_info ei on e_i.emp_id = ei.emp_id
join examination_info emi on e_i.exam_id = emi.exam_id
ORDER BY e_i.emp_id asc, e_i.exam_id asc
受不了了,先没看到判断优秀的条件,以为第一名就行,直接rank→发现要高于平均,结果出来多了员工→发现平均还要包括高职级的,之前只算了普通员工的平均→还是多,疑惑,接着发现还有平均时间要短于平均→终于写出来了石山
发表于 2026-02-06 11:19:48 回复(0)
有意思
with t1 as (
    select er.exam_id, exa.tag,
    avg(timestampdiff(second, start_time, submit_time)) as avg_duration,
    avg(er.score) as avg_score
    from exam_record er
    left join examination_info exa
    on er.exam_id = exa.exam_id
    group by er.exam_id, exa.tag
),

t2 as (
    select er.emp_id, er.exam_id, er.score,
    timestampdiff(second, start_time, submit_time) as duration_each,
    ei.emp_level
    from exam_record er
    left join emp_info ei
    on er.emp_id = ei.emp_id
    where ei.emp_level < 7
)

select t2.emp_id, t2.emp_level,
t1.tag as exam_tag
from t2
join t1
on t2.exam_id = t1.exam_id
where t2.duration_each < t1.avg_duration
and t2.score > t1.avg_score


发表于 2026-01-30 16:21:14 回复(0)
with aa as (select t2.tag
,t2.exam_id
,avg((unix_timestamp(t1.submit_time)-unix_timestamp(t1.start_time))) avg_time
,avg(t1.score) avg_score
from exam_record t1 
left join examination_info t2 
on t1.exam_id=t2.exam_id
group by t2.tag,t2.exam_id

)

select t1.emp_id
,t3.emp_level
,t2.tag exam_tag
from exam_record t1 
left join examination_info t2 
on t1.exam_id=t2.exam_id
left join emp_info t3 
on t1.emp_id=t3.emp_id
left join aa t4 
on t4.exam_id=t1.exam_id
where t1.score>t4.avg_score
and (unix_timestamp(t1.submit_time)-unix_timestamp(t1.start_time))<t4.avg_time
and t1.emp_id not in (
    select distinct emp_id
    from emp_info 
    where emp_level>=7
)
order by t1.emp_id,t1.exam_id




发表于 2026-01-28 13:53:35 回复(0)
SELECT DISTINCT
    er.emp_id,
    emp.emp_level,
    ei.tag
FROM
    exam_record er
    INNER JOIN emp_info emp ON er.emp_id = emp.emp_id
    INNER JOIN examination_info ei ON er.exam_id = ei.exam_id
    INNER JOIN (
        SELECT
            exam_id,
            AVG(score) as avg_score,
            AVG(TIMESTAMPDIFF(SECOND, start_time, submit_time)) as avg_seconds
        FROM
            exam_record
        GROUP BY
            exam_id
    ) t ON er.exam_id = t.exam_id
WHERE
    emp.emp_level < 7
    AND er.score > t.avg_score
    AND TIMESTAMPDIFF(SECOND, er.start_time, er.submit_time) < t.avg_seconds

发表于 2026-01-28 00:28:25 回复(0)
# 1.计算试卷平均时间和平均分数
with a as
(select exam_id,avg(timestampdiff(second,start_time,submit_time)) as avg_time,
avg(score) as avg_score
from exam_record
group by exam_id)
# 2.计算目标人群
select e1.emp_id,emp_level,tag as exam_tag
from a join exam_record e1 on a.exam_id = e1.exam_id join emp_info e2 on e1.emp_id = e2.emp_id join examination_info e3 on e1.exam_id = e3.exam_id
where score > avg_score and timestampdiff(second,start_time,submit_time) < avg_time and emp_level<7
order by e1.emp_id,e1.exam_id

发表于 2026-01-25 10:43:25 回复(0)
刚开始以为可以直接用表连接和子查询做出来 结果整半天都没想起用窗口函数 还是看了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)
with t1 as (select t1.emp_id,t1.exam_id,tag,emp_name,emp_level,timestampdiff(second,start_time,submit_time)/60 as time,score
from exam_record t1
join emp_info t2 on t1.emp_id=t2.emp_id
join examination_info t3 on t1.exam_id=t3.exam_id
),
t2 as(select t1.exam_id,avg(score) as 平均分,avg(time) as 平均时间
from t1
group by t1.exam_id)
select t1.emp_id,emp_level,tag as emp_tag
from t1
left join t2 on t1.exam_id=t2.exam_id
where emp_level<7 and score>平均分 and time<平均时间
order by t1.emp_id,t1.exam_id
发表于 2026-01-20 19:44:14 回复(0)
# 每条考试记录的该考试平均分和平均作答时间;领导不算
WITH t AS (
    SELECT *, AVG(score) OVER (PARTITION BY exam_id) AS avg_score,
        AVG(TIMESTAMPDIFF(SECOND, start_time, submit_time)) OVER (PARTITION BY exam_id) AS avg_t
    FROM exam_record JOIN emp_info USING (emp_id)
    JOIN examination_info USING (exam_id)
    WHERE emp_level < 7
)
SELECT emp_id, emp_level, tag AS exam_tag
FROM t
WHERE score > avg_score AND TIMESTAMPDIFF(SECOND, start_time, submit_time) < avg_t
ORDER BY 1
首先答案表格颗粒度是一条考试记录,也就是说把每条考试记录所属于考试id的均分和平均时长算出来,然后筛选就行
发表于 2026-01-14 12:06:00 回复(0)
select
    emp_id,
    emp_level,
    tag
from(
select *,
    avg(t) over(partition by exam_id) as avg_time
from(
select
    er.emp_id,
    er.exam_id,
    ei.emp_level,
    tag,
    TIMESTAMPDIFF(second,start_time,submit_time) as t,
    score,
    avg(score) over(partition by er.exam_id) as avg_score
from exam_record as er
join emp_info  as ei
on er.emp_id=ei.emp_id
join examination_info as ex
on er.exam_id=ex.exam_id
where emp_level<7
) as a
) as b
where t<avg_time and score>avg_score
order by emp_id

发表于 2026-01-11 22:53:08 回复(0)
#找到作答每类试卷的突出非领导员工,并输出他们的员工ID,员工等级和突出试卷类别并按照员工ID升序排序,若某员工两类试卷都突出,则按照试卷ID升序排序
#作答用时少于同类试卷平均值且个人分数大于同类试卷总体平均值的员工记为该类型的突出员工。
考虑这类型题首先要把聚合值求出,然后连接表,条件筛选
select  em.emp_id,emp_level,exam_tag from(
select er.exam_id,tag as exam_tag,avg(timestampdiff(second,start_time,submit_time)) as avg_time,avg(score) as avg_score
from exam_record er  join examination_info ei on er.exam_id =ei.exam_id
group by  er.exam_id ,tag)t1
join  exam_record  er on t1.exam_id = er.exam_id
join emp_info em  on er.emp_id =em.emp_id and score > avg_score and timestampdiff(second,start_time,submit_time) < avg_time
where  emp_level < 7
order by em.emp_id asc  

发表于 2026-01-10 18:24:36 回复(0)