首页 > 试题广场 >

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

[编程题]完成员工考核试卷突出的非领导员工
  • 热度指数:8614 时间限制: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|企业文化
不是.......这题目有问题吧,哪里说了等级要求了........?
发表于 2025-01-30 16:53:40 回复(4)
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 回复(1)
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)
这种题目都一个套路,先看有没有额外的表产生,然后再看限制条件是不是可以用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 回复(1)
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)
很简单的一题,可以认为是窗口函数例题。

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)
请问大佬们,MySQL有没有能够直接筛选出score > AVG(score)的函数,这样就不用先专门用一个SELECT获取平均分,再用外层的SELECT去筛选了。
发表于 2025-04-10 15:20:53 回复(1)
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)
写了2个临时表 有点长 但是好理解
#构建临时表t,求2种类型考试的平均考试时间和平均分数分别是多少

with t as (
    select r.exam_id,
           e.tag,
           avg(unix_timestamp(r.submit_time)-unix_timestamp(r.start_time)) as avg_time,
       avg(r.score) as avg_score
       
from exam_record as r
left join examination_info as e
on r.exam_id=e.exam_id

group by r.exam_id, e.tag ),

#构建临时表s.求员工的id,考试id,考试分数,考试时间,最后仅保留 emp_level 小于7的
q as (
    select r.emp_id,
    r.exam_id,
    ei.emp_level,
    (unix_timestamp(r.submit_time)-unix_timestamp(r.start_time)) as exam_time,
     score

from exam_record as r
left join emp_info as ei
on r.emp_id=ei.emp_id

where ei.emp_level<7
)

#主查询,仅保留考试用时小于平均用时,分数大于平均分的
select q.emp_id,
       q.emp_level,
       t.tag as exam_tag
from q
left join t
on q.exam_id=t.exam_id

where q.exam_time< t.avg_time and q.score>t.avg_score

发表于 2025-06-17 17:10:13 回复(1)
感觉我做的很麻烦,还可以优化吗

with t1 as(select emp_id,emp_level
from emp_info
where emp_level<7), -- 员工信息
t2 as( select e1.emp_id,
       e1.exam_id,
       timestampdiff(second,start_time,submit_time) time,
       score,
       e2.tag
from exam_record e1
left join examination_info e2
using(exam_id)),  -- 用时和成绩
t3 as(select tag,avg(time) time1,avg(score) score1
from t2
group by tag)  -- 各科目平均用时和分数
select emp_id,emp_level,tag exam_tag
from t2
left join t3
using(tag)
right join t1
using(emp_id)
where time<time1 and score>score1
order by emp_id asc,exam_tag asc

发表于 2025-06-16 17:23:22 回复(0)
with
    k as (
        select
            exam_id,
            avg(score) s,
            round(
                avg(
                    timestampdiff(second, start_time, submit_time) / 60
                ),
                1
            ) mm
        from
            exam_record
        group by
            exam_id
    )
select
    c.emp_id,
    emp_level,
    tag exam_tag
from
    exam_record c
    left join emp_info d on d.emp_id = c.emp_id
    left join examination_info e on e.exam_id = c.exam_id
    left join k on k.exam_id = c.exam_id
where
    emp_level < 7
    and timestampdiff(second, start_time, submit_time) / 60 < mm
    and score > s

发表于 2025-06-16 16:06:40 回复(0)
with
    t1 as (
        select
            exam_id,
            avg(timediff(submit_time, start_time)) avg_time,
            avg(score) avg_score
        from
            exam_record
        group by
            exam_id
    )
select
    e1.emp_id,
    emp_level,
    tag exam_tag
from
    emp_info e1,
    examination_info e2,
    exam_record e3,
    t1
where
    e1.emp_id = e3.emp_id
    and e2.exam_id = e3.exam_id
    and t1.exam_id = e3.exam_id
    and emp_level < 7
    and timediff(submit_time, start_time) < avg_time
    and score > avg_score
order by
    e1.emp_id

发表于 2025-06-14 20:36:09 回复(0)
WITH avg_tb AS (
    SELECT
        a.exam_id,
        tag,
        AVG(TIMESTAMPDIFF(SECOND, start_time, submit_time)) AS avg_time,
        AVG(score) AS avg_score
    FROM exam_record a
    JOIN examination_info b ON a.exam_id = b.exam_id
    GROUP BY exam_id, tag
)
SELECT
    e.emp_id,
    c.emp_level,
    a.tag AS exam_tag
FROM exam_record e
JOIN avg_tb a ON e.exam_id = a.exam_id
JOIN emp_info c ON e.emp_id = c.emp_id
    AND c.emp_level < 7
WHERE
    TIMESTAMPDIFF(SECOND, e.start_time, e.submit_time) < a.avg_time
    AND e.score > a.avg_score
ORDER BY e.emp_id, e.exam_id;
发表于 2025-06-09 20:43:33 回复(0)
with exam_time as
(
    select emp_id,exam_id,
    timestampdiff(second,start_time,submit_time) as exam_time,score
    from exam_record 
)
,t2 as(
    SELECT *
FROM (
    SELECT *,
        AVG(exam_time) OVER (PARTITION BY exam_id) AS avg_time,
        AVG(score) OVER (PARTITION BY exam_id) AS avg_score
    FROM exam_time
) t
WHERE exam_time < avg_time
  AND score > avg_score
)
select t1.emp_id,t1.emp_level,t3.tag as exam_tag
from emp_info t1
join t2 on t1.emp_id=t2.emp_id 
join examination_info t3 on t2.exam_id=t3.exam_id
where t1.emp_level<7
order by t1.emp_id,t2.exam_id

发表于 2025-06-03 17:32:53 回复(0)
select emp_id,emp_level,tag as exam_tag
from
(
select emp_id,emp_name, emp_level,register_time,exam_id, tag, duration, release_time, start_time, submit_time, score,avg(score)over(partition by tag) AS score_avg , avg(submit_time-start_time)over(partition by tag) as time_avg
from (
select E1.emp_id,emp_name, emp_level,register_time,E3.exam_id, tag, duration, release_time, start_time, submit_time, score
from exam_record as E3 join examination_info as E2 on E3.exam_id=E2.exam_id
join emp_info as E1 on E3.emp_id=E1.emp_id
where E1.emp_level<7
    )T1
)T2
where  submit_time- start_time<time_avg and score>score_avg
order by emp_id,exam_id
发表于 2025-06-03 14:18:19 回复(0)
with t as (select emp_id, exam_id, score, timestampdiff(second, start_time, submit_time) time from exam_record),
     w as # 筛选优秀员工
         (select exam_id, emp_id
          from t
                   join (select exam_id, avg(score) avg_score, avg(time) avg_time from t group by exam_id) z
                        using (exam_id)
          where t.score > avg_score
            and t.time < avg_time),
     q as (select emp_id, emp_level from emp_info where emp_level < 7) # 筛选非领导员工
select q.emp_id, emp_level, tag exam_tag
from w,
     q,
     examination_info e
where w.emp_id = q.emp_id
  and w.exam_id = e.exam_id
order by emp_id,e.exam_id

发表于 2025-05-31 14:33:06 回复(0)
select
    emp_id
    , emp_level
    , exam_tag
from
    (select
        er.emp_id
        , empi.emp_level
        , exami.exam_id
        , exami.tag as exam_tag
        , er.score
        , t1.avg_score
        , round(
            timestampdiff(
                second, start_time, submit_time)/60, 3) as time_diff
        , avg_time_diff
    from
        exam_record as er
        left join 
        (select
            exam_id
            , avg(score) as avg_score
        from
            exam_record
        group by
            exam_id
        ) as t1 on er.exam_id = t1.exam_id
        left join
        (select
            exam_id
            , avg(
                round(
                    timestampdiff(second, start_time, submit_time)/60, 3)) as avg_time_diff
        from
            exam_record
        group by
            exam_id
        ) as t2 on er.exam_id = t2.exam_id
        left join emp_info as empi on er.emp_id = empi.emp_id
        left join examination_info as exami on er.exam_id = exami.exam_id
    where
        empi.emp_level < 7
        and er.score > t1.avg_score
    ) as tt1
where
    time_diff < avg_time_diff
order by
    emp_id
    , exam_id

发表于 2025-05-23 16:25:34 回复(0)
select b.emp_id,e2.emp_level,tag as eaxm_tag
from
(
select ee.emp_id,ee.exam_id,score,timestampdiff(second,start_time,submit_time)/60 as time
from  exam_record ee left join
(
select exam_id,avg(score) as avgscore,round(avg(timestampdiff(second,start_time,submit_time))/60,1) as avgtimes
from exam_record
group by exam_id
)a on ee.exam_id=a.exam_id
where ee.score>a.avgscore and timestampdiff(second,start_time,submit_time)/60 <a.avgtimes
)b left join  emp_info e2
on b.emp_id=e2.emp_id
left join examination_info e3
on b.exam_id=e3.exam_id
where e2.emp_level<7
发表于 2025-05-22 22:24:46 回复(0)
WITH 
  temp1 AS(
    SELECT er.emp_id, emp_level, er.exam_id, tag, score,
        TIMESTAMPDIFF(SECOND, start_time, submit_time) AS time
    FROM exam_record er
    JOIN examination_info USING (exam_id)
    JOIN emp_info USING (emp_id)
  ),
  temp2 AS(
    SELECT *,
        AVG(score) OVER (PARTITION BY exam_id) AS avg_score,
        AVG(time) OVER (PARTITION BY exam_id) AS avg_time
    FROM temp1
  )

SELECT emp_id, emp_level, tag AS exam_tag
FROM temp2
WHERE time < avg_time AND score > avg_score AND emp_level < 7
ORDER BY emp_id, exam_id

发表于 2025-05-19 00:04:56 回复(0)
思路不清晰,得努力
with t1 as (
    select
        avg(timestampdiff(minute,start_time,submit_time)) as at,
        avg(score) as ag,
        er.exam_id
    from 
        emp_info join exam_record as er on emp_info.emp_id = er.emp_id
        where emp_level < 7 
        group by er.exam_id
)
select 
 er.emp_id,ef.emp_level as emp_level,ei.tag as exam_tag
 from 
exam_record as er join t1 on t1.exam_id = er.exam_id and timestampdiff(minute,start_time,submit_time) < at and er.score > t1.ag join examination_info as ei on ei.exam_id = er.exam_id join emp_info as ef on ef.emp_id = er.emp_id
where emp_level < 7


发表于 2025-05-18 22:18:25 回复(0)