转载声明:本文章为个人总结笔记,主要参考韩老师msql教程的SQL语句练习部分,转载需要注明参考文献的出处,尊重各位原创作者。

练习1

练习1语句

  1. -- 写出查看DEPT表和EMP表的结构的sql语句:
  2. -- (1)显示所有部门名称。
  3. -- (2)显示所有雇员名及其全年收入13月(工资+补助),并指定列别名“年收入”
  4. -- 限制查询数据。
  5. -- (1)显示工资超过2850的雇员姓名和工资。
  6. -- (2)显示工资不在15002850之间的所有雇员名及工资。
  7. -- (3)显示编号为7566的雇员姓名及所在部门编号。
  8. -- (4)显示部门1030中工资超过1500的雇员名及工资。
  9. -- (5)显示无管理者的雇员名及岗位。
  10. -- 排序数据。
  11. -- (1)显示在199121日到199151日之间雇用的雇员名,岗位及雇佣日期,并以雇佣日期进行排序。
  12. -- (2)显示获得补助的所有雇员名,工资及补助,并以工资降序排序

练习1语句参考答案

  1. -- 写出查看DEPT表和EMP表的结构的sql语句
  2. DESC `department`;
  3. DESC `emp`
  4. -- 使用简单查询语句完成:DEPT表和EMP
  5. -- (1)显示所有部门名称。
  6. SELECT dname FROM `department`;
  7. -- (2)显示所有雇员名及其全年收入13月(工资+补助),并指定列别名“年收入”
  8. /*
  9. 注意:具体的数和null相加会变成null值
  10. 思路:部分员工的补助值为null,与工资相加的和值为null,查询结果错误。
  11. 应该在相加前对补助进行非空判断
  12. IFNULL(expr1,expr2):如果expr1的值为null,则返回expr2的值,如果expr1的值不为null,则返回expr1的值
  13. */
  14. SELECT
  15. ename,(
  16. sal + IFNULL( comm, 0 ))* 13 AS '年收入'
  17. FROM
  18. `emp`;
  19. -- 限制查询数据。
  20. -- (1)显示工资超过2850的雇员姓名和工资。
  21. SELECT ename,sal FROM `emp` WHERE sal> 2850;
  22. -- (2)显示工资不在15002850之间的所有雇员名及工资。
  23. select ename,sal from `emp`
  24. where sal not between 1500 and 2850;
  25. select ename,sal from `emp`
  26. where sal < 1500 or sal > 2850;
  27. select ename,sal from `emp`
  28. where not(sal >= 1500 and sal <= 2850)
  29. -- (3)显示编号为7566的雇员姓名及所在部门编号。
  30. select ename,deptno
  31. from `emp`
  32. where empno = 7566;
  33. -- (4)显示部门1030中工资超过1500的雇员名及工资。
  34. SELECT ename, sal
  35. FROM `emp`
  36. WHERE sal > 1500 AND deptno IN ( 10, 30 );
  37. -- (5)显示无管理者的雇员名及岗位。
  38. select ename,job
  39. from `emp`
  40. where mgr is null;
  41. -- 排序数据。
  42. -- (1)显示在199121日到199151日之间雇用的雇员名,岗位及雇佣日期,并以雇佣日期进行排序。
  43. select ename,job,hiredate from `emp`
  44. where hiredate >= '1991-02-01' and hiredate <='1991-05-01'
  45. order by hiredate;
  46. select ename,job,hiredate from `emp`
  47. where hiredate between '1991-02-01' and '1991-05-01'
  48. order by hiredate;
  49. -- (2)显示获得补助的所有雇员名,工资及补助,并以工资降序排序
  50. select ename,sal,comm from `emp`
  51. where comm is not null
  52. order by sal desc;

练习2

练习2语句

  1. -- 根据:emp员工表
  2. -- 1.选择部门30中的所有员工.
  3. -- 2.列出所有办事员(CLERK)的姓名,编号和部门编号.
  4. -- 3.找出佣金高于薪金的员工.
  5. -- 4.找出佣金高于薪金60%的员工.
  6. -- 5.找出部门10中所有经理(MANAGER)和部门20中所有办事员(CLERK)的详细资料.
  7. -- 6.找出部门10中所有经理(MANAGER),部门20中所有办事员(CLERK),还有既不是经理又不是办事员但其薪金大于或等于2000的所有员工的详细资料.
  8. -- 7.找出收取佣金的员工的不同工作.
  9. -- 8.找出不收取佣金或收取的佣金低于100的员工.
  10. -- 9.找出各月倒数第3天受雇的所有员工.
  11. -- 10.找出早于12年前受雇的员工.
  12. -- 11.以首字母小写的方式显示所有员工的姓名.
  13. -- 12.显示正好为5个字符的员工的姓名.

练习1语句参考答案

  1. -- 根据:emp员工表 写出正确SQL homework03.sql
  2. -- 1.查询出部门30中的所有员工.
  3. select * from `emp`
  4. where deptno = 30;
  5. -- 2.列出所有办事员(CLERK)的姓名,编号和部门编号.
  6. select ename,empno,deptno,job from `emp`
  7. where job = 'CLERK';
  8. -- 3.找出佣金高于薪金的员工.
  9. select * from `emp`
  10. where IFNULL(comm,0) > sal;
  11. -- 4.找出佣金高于薪金60%的员工.
  12. select * from `emp`
  13. where IFNULL(comm,0) > (sal* 0.6);
  14. -- 5.找出部门10中所有经理(MANAGER)和部门20中所有办事员(CLERK)的详细资料.
  15. select *
  16. from `emp`
  17. where (job = 'MANAGER' and deptno = 10)
  18. or (job = 'CLERK' and deptno = 20)
  19. -- 6.找出部门10中所有经理(MANAGER),部门20中所有办事员(CLERK),还有既不是经理又不是办事员但其薪金大于或等于2000的所有员工的详细资料.
  20. select * from
  21. `emp`
  22. where (job = 'MANAGER' and deptno = 10)
  23. or (job = 'CLERK' and deptno = 20)
  24. or (job != 'CLERK' and job != 'MANAGER' and sal >= 2000)
  25. select * from `emp`
  26. where job = 'MANAGER' and deptno = 10
  27. UNION
  28. select * from `emp`
  29. where job = 'CLERK' and deptno = 20
  30. UNION
  31. select * from `emp`
  32. where job not in('MANAGER','CLERK')
  33. and sal >=2000;
  34. -- 7.找出收取佣金的员工的不同工作.
  35. select DISTINCT job
  36. from `emp`
  37. where comm is not null;
  38. -- 8.找出不收取佣金或收取的佣金低于100的员工.
  39. select ename,comm from `emp`
  40. where comm is null
  41. or IFNULL(comm,0) < 100;
  42. -- 9.找出各月倒数第3天受雇的所有员工.
  43. -- 提示: LAST_DAY(date) 表示某日期所在月份的最后一天
  44. select * from
  45. `emp`
  46. where hiredate = LAST_DAY(hiredate) - 2
  47. -- 10.找出早于12年前受雇的员工.
  48. /*
  49. -------------------------------
  50. | 12 |
  51. start now
  52. */
  53. SELECT *from `emp`
  54. where (YEAR(NOW()) - YEAR(hiredate) >= 12);
  55. -- 11.以首字母小写的方式显示所有员工的姓名.
  56. /*
  57. CONCAT(str1,str2) :拼接两个字符串
  58. SUBSTRING(str,start,length):截取从start开始包括start的字符
  59. LOWER(str):将字符串str的字母都转为小写
  60. */
  61. select CONCAT(LOWER(SUBSTRING(ename,1,1)),SUBSTRING(ename,2)) as '员工姓名'
  62. from `emp`;
  63. -- 12.显示正好为5个字符的员工的姓名.
  64. select ename
  65. from `emp`
  66. where LENGTH(ename) = 5

练习3

练习3语句

  1. -- 根据:emp员工表 写出正确SQL homework03.sql
  2. -- 13.显示不带有"R"的员工的姓名.
  3. --
  4. -- 14.显示所有员工姓名的前三个字符
  5. --
  6. -- 15.显示所有员工的姓名,用a替换所有“A
  7. --
  8. -- 16.显示满10年服务年限的员工的姓名和受雇日期.
  9. --
  10. -- 17.显示员工的详细资料,按姓名排序.
  11. --
  12. -- 18.显示员工的姓名和受雇日期,根据其服务年限,将最老的员工排在最前面.
  13. --
  14. -- 19.显示所有员工的姓名、工作和薪金,按工作降序排序,若工作相同则按薪金排序.
  15. --
  16. -- 20.显示所有员工的姓名、加入公司的年份和月份,按受雇日期所在月排序,若月份相同则将最早年份的员工排在最前面.
  17. --
  18. -- 21.显示在一个月为30天的情况所有员工的日薪金,忽略余数.
  19. --
  20. -- 22.找出在(任何年份的)2月受聘的所有员工。
  21. --
  22. -- 23.对于每个员工,显示其加入公司的天数.
  23. --
  24. -- 24.显示姓名字段的任何位置包含"A"的所有员工的姓名.
  25. --
  26. -- 25.以年月日的方式显示所有员工的服务年限.(大概)

练习3语句参考答案

  1. -- 根据:emp员工表
  2. -- 13.显示不带有"R"的员工的姓名.
  3. select * from `emp`
  4. where ename not like '%R%';
  5. -- 14.显示所有员工姓名的前三个字符
  6. /*
  7. LEFT(str,length):字符串函数,返回具有指定长度的字符串的左边部分
  8. str是要提取子字符串的字符串。
  9. length是一个正整数,指定将从左边返回的字符数。
  10. */
  11. select LEFT(ename,3) FROM `emp`;
  12. select SUBSTRING(ename,1,3) as '姓名简称' from `emp`;
  13. -- 15.显示所有员工的姓名,用a替换所有“A
  14. select REPLACE(ename,'A','a') from `emp`;
  15. -- -16.显示满10年服务年限的员工的姓名和受雇日期
  16. -- 提示:DATE_ADD(date,INTERVAL expr unit):在date中加上日期或时间
  17. select ename,hiredate from `emp`
  18. where DATE_ADD(hiredate,INTERVAL 10 year) <= NOW()
  19. -- -17.显示员工的详细资料,按姓名排序.
  20. select * from `emp` order by ename;
  21. -- -18.显示员工的姓名和受雇日期,根据其服务年限,将最老的员工排在最前面.
  22. select ename,hiredate from `emp`
  23. order by hiredate asc;
  24. -- -----19.显示所有员工的姓名、工作和薪金,按工作降序排序,若工作相同则按薪金排序.
  25. select ename,job,sal
  26. from `emp`
  27. order by job desc,sal asc;
  28. -- 20.显示所有员工的姓名、加入公司的年份和月份,按受雇日期所在月排序,若月份相同则将最早年份的员工排在最前面.
  29. select ename,CONCAT(YEAR(hiredate),'-',MONTH(hiredate)) as '入职年月份' from `emp`
  30. order by MONTH(hiredate) asc,YEAR(hiredate) asc
  31. -- -21.显示在一个月为30天的情况所有员工的日薪金,忽略余数.
  32. select ename,ROUND(sal / 30) as '日薪资' from `emp`;
  33. -- -22.找出在(任何年份的)2月受聘的所有员工。
  34. select * from `emp`
  35. where (MONTH(hiredate))=2
  36. -- -23.对于每个员工,显示其加入公司的天数.
  37. select ename,DATEDIFF(NOW(),hiredate) as '工作天数' from `emp`;
  38. -- -24.显示姓名字段的任何位置包含"A"的所有员工的姓名.
  39. select ename from `emp`
  40. where ename like '%A%';
  41. -- -25.以年月日的方式显示所有员工的服务年限.(大概)
  42. -- 提示:工作了xxxxxxxx
  43. select ename,
  44. FLOOR(DATEDIFF(NOW(),hiredate) / 365) as '工作年数',
  45. FLOOR(DATEDIFF(NOW(),hiredate) % 365 / 31) as '工作月数',
  46. DATEDIFF(NOW(),hiredate) % 31 as '工作天数'
  47. from `emp`

练习4

练习4语句

  1. -- 根据:emp员工表,dept部门表
  2. -- 友情提示:工资=薪金+佣金
  3. -- (1).列出至少有一个员工的所有部门
  4. -- (2).列出薪金比“SMITH”多的所有员工。
  5. -- (3).列出受雇日期晚于其直接上级的所有员工。
  6. -- (4).列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门。
  7. -- (5).列出所有“CLERK”(办事员)的姓名及其部门名称。
  8. -- (6).列出最低薪金大于1500的各种工作。
  9. -- (7).列出在部门“SALES”(销售部)工作的员工的姓名。
  10. -- (8).列出薪金高于公司平均薪金的所有员工。

练习4语句参考答案

  1. -- 根据:emp员工表,dept部门表,工资=薪金+佣金
  2. -- (1).列出至少有一个员工的所有部门
  3. select deptno,count(*) as number
  4. from `emp`
  5. group by deptno
  6. having number >=1;
  7. -- (2).列出薪金比“SMITH”多的所有员工。
  8. /*
  9. 1.查询出员工名字为‘SMITH’的薪资 作为子查询条件
  10. 2.查询工资比step1高的所有员工
  11. */
  12. SELECT
  13. ename,sal
  14. FROM `emp`
  15. WHERE sal > (
  16. SELECT sal FROM `emp`
  17. WHERE ename = 'SMITH')
  18. -- (3).列出受雇日期晚于其直接上级的所有员工。
  19. /*
  20. 关键:自连接
  21. */
  22. select worker.ename '员工名称',worker.hiredate '员工受雇日期',
  23. leader.ename '领导名称',leader.hiredate '领导受雇日期'
  24. from `emp` worker,`emp` leader
  25. where worker.mgr = leader.empno
  26. and worker.hiredate > leader.hiredate;
  27. -- (4).列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门。
  28. select dname,e.*
  29. from `department` as d
  30. left join `emp` as e
  31. on d.deptno = e.deptno;
  32. -- (5).列出所有“CLERK”(办事员)的姓名及其部门名称。
  33. select ename,dname,job
  34. from `emp` e,`department` d
  35. where e.deptno = d.deptno
  36. and job = 'CLERK';
  37. -- (6).列出最低薪金大于1500的各种工作。
  38. select min(sal) min_sal, job
  39. from `emp`
  40. group by job having min_sal > 1500;
  41. -- (7).列出在部门“SALES”(销售部)工作的员工的姓名。
  42. select ename
  43. from `emp` e, `department` d
  44. where e.deptno = d.deptno
  45. and dname = 'SALES';
  46. -- (8).列出薪金高于公司平均薪金的所有员工。
  47. select AVG(sal)
  48. from `emp`
  49. group by empno sal > AVG(sal);

练习5

练习5语句

  1. -- 根据:emp员工表,dept部门表,工资=薪金+佣金
  2. -- (9).列出与“SCOTT”从事相同工作的所有员工。
  3. -- (10).列出薪金高于在部门30工作的所有员工的薪金的员工姓名和薪金。
  4. -- (11).列出在每个部门工作的员工数量、平均工资和平均服务期限。
  5. -- (12).列出所有员工的姓名、部门名称和工资。
  6. -- (13).列出所有部门的详细信息和部门人数。
  7. -- (14).列出各种工作的最低工资。
  8. -- (15).列出MANAGER(经理)的最低薪金。
  9. -- (16).列出所有员工的年工资,按年薪从低到高排序。

练习5语句参考答案

  1. -- (9).列出与“SCOTT”从事相同工作的所有员工。
  2. /*
  3. 1.查询员工“SCOTT”从事的工作
  4. 2.step1作为子查询条件,查询相同工作的其他员工
  5. */
  6. SELECT ename,job
  7. FROM `emp`
  8. WHERE job = ( SELECT job FROM `emp` WHERE ename = 'SCOTT' ) and ename != 'SCOTT';
  9. -- (10).列出薪金高于在部门30工作的所有员工的薪金的员工姓名和薪金。
  10. /*
  11. 1.先查出30部门的最高工资
  12. 2.step1作为子查询条件,查询比step1工资高的员工姓名和薪资
  13. */
  14. select ename,sal
  15. from `emp`
  16. where sal > (
  17. select max(sal) max_sal
  18. from `emp`
  19. where deptno = 30
  20. )
  21. -- avg(DATEDIFF(NOW(),hiredate)
  22. -- (11).列出在每个部门工作的员工数量、平均工资和平均服务期限。
  23. /*
  24. 1.每个部门 按部门分组
  25. 2.查询每个部门的员工数量
  26. 3.查询每个部门的平均工资
  27. 4.查询每个部门的服务期限 DATEDIFF(expr1,expr2)
  28. */
  29. select deptno,
  30. count(*) as '员工数量',
  31. avg(sal) as '平均工资',
  32. avg(DATEDIFF(NOW(),hiredate)) as '平均价格'
  33. from `emp`
  34. group by deptno;
  35. -- (12).列出所有员工的姓名、部门名称和工资。
  36. select ename,dname,sal
  37. from `emp` e,`department` d
  38. where e.deptno = d.deptno
  39. -- (13).列出所有部门的详细信息和部门人数。
  40. /*
  41. 1.查询部门人数 作为临时表 tmp
  42. 2.临时表tmp和部门表department联表查询 部门的详细信息和部门人数
  43. */
  44. select deptno,dname,loc,number
  45. from `department`,(select count(*) number from `emp` group by deptno) `tmp`
  46. -- (14).列出各种工作的最低工资。
  47. select job,MIN(sal) as min_sal from `emp`
  48. group by job;
  49. -- (15).列出MANAGER(经理)的最低薪金。
  50. select MIN(sal)
  51. from `emp`
  52. where job = 'MANAGER' ;
  53. -- (16).列出所有员工的年工资,按年薪从低到高排序。
  54. /*
  55. 1.查询员工的年工资
  56. 2.按年薪降序升序
  57. */
  58. select ename,( (sal + IFNULL(comm,0) ) * 12) as total_sal
  59. from `emp`
  60. order by total_sal asc;

练习基于的数据表

  • 数据表模型

image.png
细节说明:为方面练习,并为设置主外健

  • 练习所需的数据表相关数据 ```plsql

    创建员工表 emp

    CREATE TABLE emp ( empno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0 COMMENT ‘员工编号’, ename VARCHAR ( 20 ) NOT NULL DEFAULT ‘’ COMMENT ‘员工名称’, job VARCHAR ( 9 ) NOT NULL DEFAULT ‘’ COMMENT ‘员工岗位’, mgr MEDIUMINT UNSIGNED COMMENT ‘领导编号’, hiredate DATE NOT NULL COMMENT ‘受雇日期’, sal DECIMAL ( 7, 2 ) COMMENT ‘员工工资’, comm DECIMAL ( 7, 2 ) COMMENT ‘员工补贴’, deptno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0 COMMENT ‘部门编号’ );

    emp中插入数据

    INSERT INTO emp VALUES ( 7369, ‘SMITH’, ‘CLERK’, 7902, ‘1990-12-17’, 800.00, NULL, 20 ), ( 7499, ‘ALLEN’, ‘SALESMAN’, 7698, ‘1991-2-20’, 1600.00, 300.00, 30 ), ( 7521, ‘WARD’, ‘SALESMAN’, 7968, ‘1991-2-22’, 1250.00, 500.00, 30 ), ( 7566, ‘JONES’, ‘MANAGER’, 7839, ‘1991-4-2’, 2975.00, NULL, 20 ), ( 7654, ‘MARTIN’, ‘SALESMAN’, 7968, ‘1991-9-28’, 1250.00, 1400.00, 30 ), ( 7698, ‘BLAKE’, ‘MANAGER’, 7839, ‘1991-5-1’, 2850.00, NULL, 30 ), ( 7782, ‘CLARK’, ‘MANAGER’, 7839, ‘1991-6-9’, 2450.00, NULL, 10 ), ( 7788, ‘SCOTT’, ‘ANALYST’, 7566, ‘1991-4-19’, 3000.00, NULL, 20 ), ( 7839, ‘KING’, ‘PRESIDENT’, NULL, ‘1991-11-17’, 5000.00, NULL, 10 ), ( 7844, ‘TURNER’, ‘SALESMAN’, 7698, ‘1991-9-8’, 1500.00, NULL, 30 ), ( 7900, ‘JAMES’, ‘CLERK’, 7698, ‘1991-12-3’, 950.00, NULL, 30 ), ( 7902, ‘FORD’, ‘ANALYST’, 7566, ‘1991-12-3’, 3000.00, NULL, 20 ), ( 7934, ‘MILLER’, ‘CLERK’, 7782, ‘1991-1-23’, 1300.00, NULL, 10 );

创建部门表department

CREATE TABLE department ( deptno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0 COMMENT ‘部门编号’, dname VARCHAR ( 20 ) NOT NULL DEFAULT ‘’ COMMENT ‘部门名称’, loc VARCHAR ( 13 ) NOT NULL DEFAULT ‘’ COMMENT ‘部门所在地’ );

department表中插入数据

INSERT INTO department VALUES ( 10, ‘ACCOUNTING’, ‘BEIJING’ ), ( 20, ‘RESEARCH’, ‘SHANGHAI’ ), ( 30, ‘SALES’, ‘NANJING’ ), ( 40, ‘OPERATIONS’, ‘CHENGDU’ );

```

数据表创建练习

参考文献