宁波保税港-数据分析实习笔试题目

125 阅读4分钟

SQL

数据

 -- 创建工资表 tsalary
 CREATE TABLE IF NOT EXISTS t_salary (
  id INT PRIMARY KEY AUTO_INCREMENT, -- 假设id是一个自增的主键
  dep_no VARCHAR(10), -- 部门编号
  user_no VARCHAR(10), -- 用户编号
  user_name VARCHAR(50), -- 姓名
  month VARCHAR(7), -- 年月,格式为 'YYYY-MM'
  salary DECIMAL(10, 2) -- 工资,假设工资精确到小数点后两位
 );
 ​
 -- 插入数据到工资表 tsalary
 INSERT INTO t_salary (dep_no, user_no, user_name, month, salary) VALUES
 ('101', '001', '小王', '2024-01', 100),
 ('101', '001', '小王', '2024-02', 200),
 ('101', '002', '小李', '2024-02', 140),
 ('101', '001', '小王', '2024-03', 500);
 ​
 ​
 -- 创建部门表 t_department
 CREATE TABLE if not EXISTS t_department (
     id INT PRIMARY KEY AUTO_INCREMENT, -- 假设id是一个自增的主键
     dep_no VARCHAR(10),               -- 部门编号
     dep_name VARCHAR(50),             -- 部门名称
     user_count INT                    -- 部门人数
 );
 ​
 -- 插入数据到部门表 t_department
 INSERT INTO t_department (dep_no, dep_name, user_count) VALUES
 ('101', '市场部', 4);

问题一

编写SQL查询每个人每月的累计工资(1月=1月,2月=2月+1月,3月=3月+2月+1月......)

SQL实现

 SELECT 
     user_name as '姓名',
     month as '年月',
     (
         SELECT 
             SUM(salary) 
          FROM t_salary 
          WHERE user_no = outer_user.user_no AND month <= outer_user.month           -- 筛选 小于等于 当前日期的数据
     ) AS '累计工资'
 FROM 
     (
         SELECT 
             DISTINCT user_no
             ,user_name
             ,month 
         FROM t_salary
     ) AS outer_user
 ORDER BY 
     user_no, 
     STR_TO_DATE(month, '%Y-%m');

输出示例

 姓名  年月    累计工资
 小王  2024-01 100.00
 小王  2024-02 300.00
 小王  2024-03 800.00
 小李  2024-02 140.00

问题二

编写SQL查询每个月平均工资在每个段位的人数,[0, 100) A,[100, 200) B ,[200, 300) C,300及以上 D

SQL实现

 select 
     month AS '年月'
     ,sum(case when avg_salary >= 0 and avg_salary < 100 then 1 else 0 end) as 'A人数'
     ,sum(case when avg_salary >= 100 and avg_salary < 200 then 1 else 0 end) as 'B人数'
     ,sum(case when avg_salary >= 200 and avg_salary < 300 then 1 else 0 end) as 'C人数'
     ,sum(case when avg_salary >= 300 then 1 else 0 end) as 'D人数'
 from 
     (
         select 
             month
             ,user_no
             ,round(avg(salary),2) as avg_salary
         from t_salary
         group by user_no,month
     ) as salary_by_user
 group by month

输出示例

 年月    A人数 B人数 C人数 D人数
 2024-01 0   1   0   0
 2024-02 0   1   1   0
 2024-03 0   0   0   1

问题三

编写SQL查询每个月每个部门的信息和发了工资的人数和总金额,结果格式如下

SQL实现

 select 
     t.`month` as '年月'
     ,dep.dep_no as '部门编号'
     ,dep.dep_name as '部门名称'
     ,dep.user_count as '部门人数'
     ,t.sum_emp as '发放工资的人数'
     ,t.sum_salary as '工资总金额'
 from t_department dep 
 left join 
     (
         select 
             month
             ,dep_no
             ,count(user_no) as sum_emp
             ,sum(salary) as sum_salary
         from t_salary 
         where salary > 0
         group by month,dep_no
     ) as t  
     on dep.dep_no = t.dep_no
 order by t.`month`,dep.dep_no

输出示例

 年月  部门编号    部门名称    部门人数    发放工资的人数 工资总金额
 2024-01 101 市场部 4   1   100.00
 2024-02 101 市场部 4   2   340.00
 2024-03 101 市场部 4   1   500.00

问题四

编写SQL查询本月有发放工资但是上个月没有发放过工资的人的信息

SQL实现

 SELECT 
     ts.user_no AS 用户编号,
     ts.user_name AS 姓名,
     td.dep_name AS 部门名称
 FROM t_salary ts
 LEFT JOIN t_department td ON ts.dep_no = td.dep_no
 WHERE 
     ts.month = '2024-02' -- 本月
     AND NOT EXISTS (
         SELECT 1 
         FROM t_salary ts_prev
         WHERE ts_prev.user_no = ts.user_no
         AND ts_prev.month = '2024-01' -- 上月
     );

输出示例

 用户编号    姓名  部门名称
 002       小李    市场部

问题五

编写SQL查询历史所有工资数据中存在过连续三个月都是工资最高的人的用户信息

SQL实现

 select
     user_no
     ,user_name
     ,dep_no
 from 
     (
             -- 每月工资最高,员工id、员工名称、部门名称、月份、工资
             select 
                  user_no
                 ,user_name
                 ,dep_no
                 ,month 
                 ,salary 
                 ,lag(user_no,1) over (order by month) as lag_user_no    -- 用于筛选三个月工资是否相等
                 ,lead(user_no,1) over (order by month) as lead_user_no  -- 每月工资最高,员工id、员工名称、工资
             from t_salary
             where 
                 salary in 
                 (
                     -- 每月最高的工资
                     select 
                         max(salary)
                     from t_salary 
                     group by month
                 ) 
             order by month
     ) as t 
 where t.user_no = t.lag_user_no and t.user_no = t.lead_user_no

输出示例

 用户编号    姓名  部门名称
 001       小王    101