zoukankan      html  css  js  c++  java
  • (sql语句试题练习及 参考答案解题思路+个人解题思路)

    SQL字段说明及数据

    =======================================================================
    一、部门表字段描述:
    dp_no 部门ID
    dp_name 部门名称
    dp_loc 部门所在地

    二、员工表字段说明:
    eNo 员工编号
    eName 员工姓名
    eJob 员工职责
    emgr 上司编号
    eHiredate 入职时间
    eSal 工资
    ecomm 扣税
    dp_no 部门ID

    创建数据库及数据表
    CREATE DATABASE IF NOT EXISTS SQLTEST;

    CREATE TABLE IF NOT EXISTS dept(
    dp_no int(10) not null primary key,
    dp_name varchar(25),
    dp_loc varchar(25)
    );

    CREATE TABLE IF NOT EXISTS EMP(
    eNo int(25) not null primary key,
    eName varchar(45),
    eJob varchar(45),
    emgr int(25),
    eHiredate date,
    eSal int(45),
    ecomm int(45),
    dp_no int(25)
    );

    添加dept表数据:
    insert into dept(dp_no, dp_name, dp_loc) values (10, 'ACCOUNTING', 'NEW YORK');
    insert into dept(dp_no, dp_name, dp_loc) values (20, 'RESEARCH', 'DALLAS');
    insert into dept(dp_no, dp_name, dp_loc) values (30, 'eSalES', 'CHICAGO');
    insert into dept(dp_no, dp_name, dp_loc) values (40, 'OPERATIONS', 'BOSTON');
    commit;

    添加EMP表数据: eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no
    insert into EMP(eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no) values (7369, 'SMITH', 'CLERK', 7902, '1980-12-17', 800, null, 20);
    insert into EMP(eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no) values (7499, 'ALLEN', 'eSalESMAN', 7698,'1981-02-20', 1600, 300, 30);
    insert into EMP(eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no) values (7521, 'WARD', 'eSalESMAN', 7698, '1981-02-22', 1250, 500, 30);
    insert into EMP(eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no) values (7566, 'JONES', 'MANAGER', 7839, '1981-04-02' , 2975, null, 20);
    insert into EMP(eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no) values (7654, 'MARTIN', 'eSalESMAN', 7698, '1981-09-28' , 1250, 1400, 30);
    insert into EMP(eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no) values (7698, 'BLAKE', 'MANAGER', 7839, '1981-05-01' , 2850, null, 30);
    insert into EMP(eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no) values (7782, 'CLARK', 'MANAGER', 7839, '1981-06-09' , 2450, null, 10);
    insert into EMP(eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no) values (7788, 'SCOTT', 'ANALYST', 7566, '1987-04-19' , 3000, null, 20);
    insert into EMP(eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no) values (7839, 'KING', 'PRESIDENT', null, '1981-11-17' , 5000, null, 10);
    insert into EMP(eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no) values (7844, 'TURNER', 'eSalESMAN', 7698, '1981-09-08' , 1500, 0, 30);
    insert into EMP(eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no) values (7876, 'ADAMS', 'CLERK', 7788, '1987-05-23' , 1100, null, 20);
    insert into EMP(eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no) values (7900, 'JAMES', 'CLERK', 7698, '1981-12-03' , 950, null, 30);
    insert into EMP(eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no) values (7902, 'FORD', 'ANALYST', 7566, '1981-12-02' , 3000, null, 20);
    insert into EMP(eNo, eName, eJob, emgr, eHiredate, eSal, ecomm, dp_no) values (7934, 'MILLER', 'CLERK', 7782, '1982-01-23' , 5000, null, 10);

    操作:

    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    SQL基本操作案例
    =======================================================================

    老师给的问题及解题思路
    【1】. 查询出JONES的领导是谁(JONES向谁报告)。
    子查询(效率低):
    select
    eName
    from
    EMP where eNo in(select emgr from EMP where eName='JONES');

    Join写法(高效):
    select
    e2.eName
    from(select emgr from EMP where eName='JONES') e1
    left join EMP e2
    on e1.emgr=e2.eNo;
    =======================================================================
    【2】.JONES领导谁。(谁向JONES报告)。
    子查询(效率低):
    select
    eName
    from EMP
    where emgr in (select emgr from EMP where eName='JONES');

    Join写法(高效):
    select
    e2.eName
    from(select eNo from EMP where eName='JONES') e1
    left join EMP e2
    on e1.eNo=e2.emgr;
    =======================================================================
    【3】. 查询各职位的员工工资的最大值,最小值,平均值,总和
    (问题:下面好像是各部门的,上面的各职位的呢?-->eJob,各职位就应该更简单,按职位分组)
    第一步:
    select eJob,max(eSal) as '最高薪资' from EMP group by eJob;
    select eJob,min(eSal) as '最低薪资' from EMP group by eJob;
    select eJob,avg(eSal) as '平均薪资' from EMP group by eJob;(要想保留小数点,round 里面不能写as,写到外面);
    第二步:
    select
    eJob,
    max(eSal) as '最低薪资',
    min(eSal) as '最低薪资',
    avg(eSal) as'平薪资均',
    sum(eSal) as'总和'
    from EMP
    group by eJob;

    ====================================================================
    【4】. 选择具有各个eJob的员工人数(提示:对eJob进行分组,题目不太清楚觉得。。。)
    select
    eJob as '职务',
    count(eJob) as '各职务人数'
    from EMP
    group by eJob;

    【5】. 查询员工最高工资和最低工资的差距,列名为DIFFERENCE;
    select max(eSal)-min(eSal) as'DIFFERENCE' from EMP;
    ====================================================================
    【6】. 查询各个管理者属下员工的最低工资,其中最低工资不能低于800,没有管理者的员工
    不计算在内
    ====================================================================
    【7】. 查询所有部门的部门名字dp_name,所在位置dp_loc,员工数量和工资平均值;
    第一步:各部门编号、员工数量和工资平均值,作为一表,用Join思想!!!
    select dp_no,count(eNO) as'员工数量',avg(eSal) as'工资平均' from EMP group by dp_no;
    B、A、各部门编号、员工数量和工资平均值

    select dp_name as'部门名',dp_loc as'位置',nums as'员工数量',avgeSal as'平均工资' from
    (select dp_no as no,count(eNO) as nums ,avg(eSal) as avgeSal from EMP group by dp_no) e
    left join dept d on d.dp_no=e.no;

    select
    d.dp_name as'部门名',
    d.dp_loc as'位置',
    e.nums as'员工数量',
    e.avgeSal as'平均工资'
    from dept d
    left join (select dp_no as no,count(eNO) as nums ,avg(eSal) as avgeSal from EMP group by dp_no) e
    on d.dp_no=e.no;

    高效:和我写的上面写的有什么区别???
    select
    d.dp_name,
    d.dp_loc,
    count(eNO),
    round(if(avg(eSal) is null,0,avg(eSal)),2) as'平均薪资'
    from dept d
    left join EMP e
    on d.dp_no=e.dp_no
    group by e.dp_no;

    ###round(xxx,2)保留两位小数点
    round(if(avg(eSal) is null,0,avg(eSal)),2) as'平均薪资'
    #####判断avg(eSal) is null,0,avg(eSal)为空时为0,否则用自己本身avg(eSal)
    if(avg(eSal) is null,0,avg(eSal))

    ====================================================================
    【8】. 查询和scott相同部门的员工姓名eName和雇用日期eHiredate
    普通写法(效率低):
    select
    e.eName,
    e.eHiredate
    from EMP e
    where dp_no=(select dp_no from EMP where eName='SCOTT');

    Join写法(高效):
    select
    e2.eName,
    e2.eHiredate
    from (select dp_no from EMP where eName='SCOTT') e1
    left join EMP e2
    on e1.dp_no=e2.dp_no;

    ====================================================================
    【9】. 查询工资比公司平均工资高的所有员工的员工号eNo,姓名eName和工资eSal。
    子查询(效率低):
    select eNo as'编号',eName as'姓名',eSal as'薪资' from EMP where
    eSal>(select avg(eSal) from EMP);

    Join查询(高效):
    select
    e2.eNO,
    e2.eName,
    e2.eSal
    from (select avg(eSal) as avg from EMP) e1
    left join EMP e2
    on e1.avg<=e2.eSal;

    ====================================================================
    【10】. 查询和姓名中包含字母u的员工在相同部门的员工的员工号eNo和姓名eName
    子查询(效率低);
    select
    eNo as'编号',
    eName as'姓名'
    from EMP
    where dp_no in (select dp_no from EMP Where eName like '%u%');

    如果in写为=号,返回的结果rows超过一行时会报下面错误,所以最好用in!
    ERROR 1242 (21000): Subquery returns more than 1 row

    Join查询1(高效,包括又u字母的名字也都被查出来了):
    select
    e2.eNo,
    e2.eName
    from( select dp_no from EMP where eName like '%u%') e1
    left join EMP e2
    on e1.dp_no=e2.dp_no;

    Join查询2(高效,去掉包括有u字母的名字):
    select
    e2.eNo,
    e2.eName
    from(select dp_no,eName from EMP where eName like '%u%') e1
    left join EMP e2
    on e1.dp_no=e2.dp_no
    where e1.eName!= e2.eName;
    =================================================================
    【11】. 查询在部门dp_loc为newYork的部门工作的员工的员工姓名eName,
    部门名称dp_name和岗位名称eJob

    子查询:
    select
    eName as'姓名',
    dp_name as'部门',
    eeJob as'职位'
    from EMP e ,dept d
    where e.dp_no =d.dp_no and d.dp_dp_loc='NEW YORK';

    select
    eName as'姓名',
    dp_name as'部门',
    eeJob as'职位'
    from dept d
    left join EMP e
    on e.dp_no =d.dp_no
    where d.dp_dp_loc='NEW YORK';

    select
    e.eName as'姓名',
    d.dp_name as'部门',
    e.eJob as'职位'
    from(select dp_no,dp_name from dept where dept.dp_loc='NEW YORK') d
    left join EMP e
    on e.dp_no =d.dp_no;

    ====================================================================
    【12】. 查询管理者是king的员工姓名eName和工资eSal
    select
    eName as '姓名',
    eSal as '薪资'
    from EMP
    where emgr in( select eNo from EMP where eName='KING');

    select
    e2.eName,
    e2.eSal
    from (select eNo from EMP where eName='KING') e1
    left join EMP e2
    on e1.eNo=e2.emgr;
    ====================================================================

    【13】. 显示ACCOUNTING部门有哪些职位
    普通查询:
    select
    eJob as'职位'
    from dept d,EMP e
    where d.dp_no=e.dp_no and d.dp_name='ACCOUNTING';

    Join写法:
    select
    e2.eJob as'职位'
    from(select dp_no from dept where dp_name='ACCOUNTING') d
    left join EMP e2
    on d.dp_no=e2.dp_no

    ====================================================================

    【14】. 各个部门中工资大于1500的员工人数及部门名称

    select
    d.dp_name,
    e.num as '薪资大于1500的各部门人数'
    from (select dp_no ,count(eNo) as num from EMP Where eSal>1500 group by dp_no) e
    left join dept d
    on e.dp_no=d.dp_no;

    ====================================================================
    【15】. 哪些员工的工资,高于整个公司的平均工资,列出员工的名字和工资(降序)
    子查询:
    select
    e.eName,
    e.eSal
    from EMP e
    where eSal > (select avg(eSal) from EMP)
    order by eSal desc;

    Join写法:
    select
    e2.eName as '高于整个公司的平均工资的员工姓名',
    e2.eSal as '对应的薪资'
    from(select avg(eSal) as avg from EMP) e1
    left join EMP e2
    on e2.eSal>e1.avg
    order by e2.eSal desc;

    ====================================================================
    【16】. 所在部门平均工资高于1500的员工名字
    (如果部门的平均工资高于1500,输出这个部门所有员工姓名)

    select
    e2.eName as '员工姓名'
    from(select dp_no,avg(eSal) as avg from EMP group by dp_no having avg>1500) e1
    left join EMP e2
    on e2.dp_no=e1.dp_no;

    select dp_no,avg(eSal) as avg from EMP group by dp_no having avg>1500
    只能用having 不能用where,having是在做分组之后过滤
    ====================================================================

    【17】. 列出各个部门中工资最高的员工的信息:员工名字、部门名称、工资(有点问题哦)

    子查询:
    select
    eName as '姓名',
    dp_no as '部门号',
    eSal as '薪资'
    from EMP where eSal in (select max(eSal) from EMP group by dp_no);

    Join写法:
    select
    e.eName as '姓名',
    d.dp_name as '部门名称',
    e.es as '薪资'
    from dept d
    left join (select eName,dp_no,max(eSal) as es from EMP group by dp_no) e
    on d.dp_no = e.dp_no;
    ====================================================================

    【18】. 哪个部门的平均工资是最高的,列出部门号、平均工资

    select
    dp_no,
    avg(eSal) as esal
    from EMP
    group by dp_no
    order by esal desc
    limit 1;

    有两个以上的部门平均薪资都是最高的怎么办?
    ====================================================================
    max怎么实现?思路:分组找到各部门平均薪资、部门号表e1,在从中找出最大值做表2为左表
    又用类似于表e1作为右边表
    select
    e3.dp_no,
    e3.avg
    from
    (
    select
    max(e1.avg) as max
    from(select dp_no,avg(eSal) as avg from EMP group by dp_no) e1
    )e2
    left join(select dp_no,avg(eSal) as avg from EMP group by dp_no) e3
    on e2.max=e3.avg;

    select

    from(select
    e1.avg as avg_max
    from(select dp_no,avg(eSal) as avg from EMP group by dp_no) e1) e2

    left join

     ---------------------------------------------------------------------------------------------------

    个人解题思路:

    -- 1.查询出JONES的领导是谁
    SELECT emgr FROM EMP WHERE eName='JONES' -- 根据员工姓名查询领导编号
    SELECT eName FROM EMP WHERE eNo=7839 -- 根据员工编号查询员工姓名
    -- 合并
    SELECT eName FROM EMP WHERE eNo=(
    SELECT emgr FROM EMP WHERE eName='JONES')
    -- 2.JONES领导谁。
    SELECT eNo FROM EMP WHERE eName='JONES' -- 根据员工姓名查找员工编号
    SELECT eNo FROM EMP WHERE emgr=7566 -- 根据员工编号查找员工姓名
    SELECT eName FROM EMP WHERE eNo IN(
    SELECT eNo FROM EMP WHERE emgr=7566 ) -- 根据上司编号查找员工姓名

    SELECT eName FROM EMP WHERE eNo IN(
    SELECT eNo FROM EMP WHERE emgr=
    (SELECT eNo FROM EMP WHERE eName='JONES') ) -- 根据上司姓名查找员工

    -- 3.查询各职位的员工工资的最大值,最小值,平均值,总和
    SELECT eSal,eJob FROM EMP -- 各职位员工工资
    SELECT MAX(eSal),eJob FROM EMP GROUP BY eJob -- 各职位员工工资最大值
    SELECT MIN(eSal),eJob FROM EMP GROUP BY eJob -- 各职位员工工资最小值
    SELECT AVG(eSal),eJob FROM EMP GROUP BY eJob -- 各职位员工工资平均值
    SELECT SUM(eSal),eJob FROM EMP GROUP BY eJob -- 各职位员工工资总和
    -- 4.选择具有各个eJob的员工人数
    -- 理解:查询选择各eJob的员工人数
    SELECT COUNT(eNo),eJob FROM EMP GROUP BY eJob
    -- 5.查询员工最高工资和最低工资的差距,列名为DIFFERENCE
    SELECT MAX(eSal) FROM EMP -- 查询员工最高工资
    SELECT MIN(eSal) FROM EMP -- 查询员工最低工资
    SELECT (MAX(eSal) - MIN(eSal))AS DIFFERENCE FROM EMP
    -- 6.查询各个管理者属下员工的最低工资,其中最低工资不能低于800,没有管理者的员工
    -- 不计算在内

    -- 首先查询管理者都有哪些员工,再计算员工的最低工资,并且最低工资不能低于800,以管理者编号分组
    SELECT emgr FROM EMP GROUP BY emgr -- 查询各个管理者编号
    -- 通过管理者编号查询员工编号,员工姓名,管理者编号,员工最低工资,以管理者编号分组
    SELECT eNo,eName,emgr,MIN(eSal) FROM EMP WHERE emgr IN(
    SELECT emgr FROM EMP GROUP BY emgr) GROUP BY emgr HAVING MIN(eSal)>=800

    -- 7.查询所有部门的部门名字dp_name,所在位置dp_loc,员工数量和工资平均值
    -- 查询所有部门的部门名字,所在位置
    SELECT dp_name,dp_loc FROM dept
    -- 根据部门id查询员工数量
    SELECT COUNT(eNo) FROM
    -- 内连接查询,分组查询
    SELECT d.dp_name,d.dp_loc,COUNT(eNo),AVG(eSal) FROM EMP e INNER JOIN dept d
    ON d.dp_no =e.dp_no GROUP BY d.dp_no
    -- 8.查询和scott相同部门的员工姓名eName和雇用日期eHiredate
    -- 查询scott所在部门id
    SELECT dp_no,eName FROM EMP WHERE eName='scott'
    -- 根据部门id查询员工姓名和雇佣日期
    SELECT eName,eHiredate FROM EMP WHERE dp_no IN(
    SELECT dp_no FROM EMP WHERE eName='scott')

    -- 9.查询工资比公司平均工资高的所有员工的员工号eNo,姓名eName和工资eSal
    SELECT AVG(eSal) FROM EMP -- 查询公司平均工资
    SELECT eSal FROM EMP GROUP BY eNo -- 查询公司员工工资
    SELECT eNo FROM EMP HAVING eSal>AVG(eSal) -- 错
    SELECT eNo,eName,eSal FROM EMP WHERE eSal>(SELECT AVG(eSal) FROM EMP) -- 正确
    -- 10.查询和姓名中包含字母u的员工在相同部门的员工的员工号eNo和姓名eName
    -- 查询姓名中包含字母u的员工及所在部门id
    SELECT eName,eNo,dp_no FROM EMP WHERE eName LIKE 'u%' OR eName LIKE '%u%' OR eName LIKE '%u'
    -- 根据部门id查询该部门中的员工号和姓名
    SELECT eName,eNo FROM EMP WHERE dp_no=30
    -- 合并
    SELECT eName,eNo FROM EMP WHERE dp_no IN(
    SELECT dp_no FROM EMP WHERE eName LIKE 'u%' OR eName LIKE '%u%' OR eName LIKE '%u')

    -- 11.查询在部门dp_loc为newYork的部门工作的员工的员工姓名eName,
    -- 部门名称dp_name和岗位名称eJob

    -- 查询部门名称为newYork的部门id
    SELECT dp_no FROM dept WHERE dp_loc='NEW YORK'
    -- 查询部门dp_loc为newYork的部门工作的员工的员工姓名eName
    SELECT eName FROM EMP WHERE dp_no=10
    -- 合并
    SELECT eName FROM EMP WHERE dp_no IN(
    SELECT dp_no FROM dept WHERE dp_loc='NEW YORK')

    -- 12.查询管理者是king的员工姓名eName和工资eSal
    -- 查询king的员工编号
    SELECT eNo FROM EMP WHERE eName='KING' -- 7839
    -- 查询上司编号是7839的员工姓名,工资eSal
    SELECT eName,eSal FROM EMP WHERE emgr=7839
    -- 合并
    SELECT eName,eSal FROM EMP WHERE emgr IN(
    SELECT eNo FROM EMP WHERE eName='KING')

    -- 13.显示ACCOUNTING部门有哪些职位
    -- 查询ACCOUNTING部门的部门id
    SELECT dp_no FROM dept WHERE dp_name='ACCOUNTING' -- 10
    -- 查询部门id为10的职位有哪些
    SELECT eJob FROM EMP WHERE dp_no=10
    -- 合并
    SELECT eJob FROM EMP WHERE dp_no IN(
    SELECT dp_no FROM dept WHERE dp_name='ACCOUNTING')

    -- 14.各个部门中工资大于1500的员工人数及部门名称
    -- 查询工资大于1500的员工编号和部门编号
    SELECT eNo,dp_no FROM EMP WHERE eSal>1500
    -- 查询各个部门编号工资大于1500的员工人数
    SELECT COUNT(eNo),dp_no FROM EMP WHERE eSal>1500 GROUP BY dp_no
    -- 根据部门编号查询部门名称
    SELECT dp_name FROM dept WHERE dp_no=10

    -- 使用内连接查询,分组查询,条件查询
    SELECT COUNT(eNo),d.dp_name FROM EMP e INNER JOIN dept d ON d.dp_no=e.dp_no
    WHERE eSal>1500 GROUP BY d.dp_no

    -- 15.哪些员工的工资,高于整个公司的平均工资,列出员工的名字和工资(降序)
    -- 同第九题
    SELECT eNo,eName,eSal FROM EMP WHERE eSal>(SELECT AVG(eSal) FROM EMP) ORDER BY eSal DESC

    -- 16.所在部门平均工资高于1500的员工名字,部门编号
    SELECT eNo,dp_no FROM EMP WHERE eSal>1500
    -- +部门名字
    SELECT e.eName,e.eSal,d.dp_name FROM EMP e INNER JOIN dept d ON d.dp_no=e.dp_no
    GROUP BY e.eNo HAVING AVG(eSal)>1500

    -- 17.列出各个部门中工资最高的员工的信息:员工名字、部门名称、工资
    -- 各部门工资最高的员工编号
    SELECT MAX(eSal),dp_no,eName FROM EMP GROUP BY dp_no
    -- 内连接,分组查询,聚合函数
    SELECT MAX(eSal),eName,d.dp_name,d.dp_no FROM EMP e INNER JOIN dept d ON e.dp_no=d.dp_no GROUP BY d.dp_no

    -- 18.哪个部门的平均工资是最高的,列出部门号、平均工资
    -- 查询各部门平均工资
    SELECT AVG(eSal) FROM EMP GROUP BY dp_no
    -- 查询平均工资最高的部门号,最高平均工资
    SELECT MAX(b),a.dp_no FROM (SELECT AVG(eSal)AS b,dp_no FROM EMP GROUP BY dp_no)AS a
    -- +部门名称
    SELECT MAX(b),a.dp_no,d.dp_name FROM (SELECT AVG(eSal)AS b,dp_no FROM EMP GROUP BY dp_no)AS a INNER JOIN dept d ON d.dp_no=a.dp_no

    成就人
  • 相关阅读:
    java-正则表达式6
    java-正则表达式5
    java-正则表达式4
    java-正则表达式3
    java-正则表达式2
    12.5
    JAVA GUI随笔
    JAVA个人知识总结
    UML关系图
    JAVA中的聚集和组合的区别和联系
  • 原文地址:https://www.cnblogs.com/pingzizhuanshu/p/8872622.html
Copyright © 2011-2022 走看看