第一章.多表查询

1.SQL书写事项

  1. (1)SQL 语言大小写不敏感。
  2. (2)SQL 可以写在一行或者多行
  3. (3)关键字不能被缩写也不能分行
  4. (4)各子句一般要分行写。
  5. (5)使用缩进提高语句的可读性。

2.字符串

  1. 日期和字符只能在单引号中出现
  2. 每当返回一行时,字符串被输出一次

3.多表查询

  1. /*
  2. 多表查询:将多张表进行连接查出需要的数据。
  3. 多表连接分类:
  4. 1.自连接 vs 非自连接
  5. 2.内连接 vs 外连接
  6. 3.等值连接 vs 非等值连接
  7. 语法:sql92语法和sql99语法(重点)
  8. */
  9. #sql92语法
  10. #需求:查询所有的员工姓名和员工所在的部门名称
  11. SELECT first_name,department_name
  12. FROM employees,departments
  13. WHERE employees.department_id=departments.department_id;#连接条件
  14. #下面会发生笛卡尔集的错误(原因:因为缺少连接条件或连接条件错误)。
  15. SELECT first_name,department_name
  16. FROM employees,departments;
  17. #需求:查询所有的员工姓名和员工所在的部门名称
  18. #注意:多表查询时,如果查询的字段在两张表中都存在那么字段名前要加表名。
  19. #如果字段可以区分最好也加上表名。因为效率高一些。
  20. SELECT employees.first_name,departments.department_name,employees.department_id,
  21. departments.`department_id`
  22. FROM employees,departments
  23. WHERE employees.department_id=departments.department_id;#连接条件
  24. #给表起别名
  25. SELECT e.first_name,d.department_name,e.department_id,
  26. d.`department_id`
  27. FROM employees e,departments d
  28. WHERE e.department_id=d.department_id;#连接条件
  29. #sql99语法
  30. /*
  31. select .....
  32. from 表1 join 表2
  33. on 连接条件
  34. join 表3
  35. on 连接条件
  36. ......
  37. where 过滤条件
  38. order by ......
  39. */
  40. #需求:查询所有的员工姓名和员工所在的部门名称
  41. #非自连接(不同的表进行连接)
  42. #等值连接(连接条件是一个等号)
  43. #内连接(所有匹配的数据)
  44. SELECT e.`first_name`,d.`department_name`
  45. FROM employees e JOIN departments d #可以写成 inner join
  46. ON e.`department_id` = d.`department_id`;
  47. #自连接
  48. #需求:获取所有的员工姓名及管理者的姓名
  49. SELECT e.`first_name` "员工姓名", m.`first_name` "管理者姓名"
  50. FROM employees e JOIN employees m
  51. ON e.`manager_id`=m.`employee_id`;
  52. #非等值连接
  53. #需求:获取所有员工的薪水等级
  54. SELECT e.`first_name`,e.`salary`,j.grade
  55. FROM employees e JOIN job_grades j
  56. ON e.salary >= j.`LOWEST_SAL` AND e.`salary` <= j.`HIGHEST_SAL`;
  57. /*
  58. 内连接: 合并具有同一列的两个以上的表的行, 结果集中不包含一个表与另一个表不匹配的行
  59. 外连接: 两个表在连接过程中除了返回满足连接条件的行以外还返回左(或右)
  60. 表中不满足条件的行 ,
  61. 这种连接称为左(或右) 外连接。没有匹配的行时, 结果表中相应的列为空(NULL).
  62. */
  63. #左外连接:
  64. #需求:获取所有的员工及员工的部门名称
  65. SELECT e.`first_name`,d.`department_name`
  66. FROM employees e LEFT JOIN departments d # 可以写成 left outer join
  67. ON e.`department_id` = d.`department_id`;
  68. #右外连接
  69. #需求:获取所有部门及部门中的员工
  70. SELECT e.`first_name`,d.`department_name`
  71. FROM employees e RIGHT JOIN departments d # 可以写成right outer join
  72. #from departments d left join employees e
  73. ON e.`department_id`=d.`department_id`;
  74. #满外连接:full join(mysql不支持)
  75. #union(去重) :可以将两条sql语句的结果进行合并
  76. #union all(不去重)
  77. SELECT e.`first_name`,d.`department_name`
  78. FROM employees e LEFT JOIN departments d
  79. ON e.`department_id` = d.`department_id`
  80. UNION
  81. SELECT e.`first_name`,d.`department_name`
  82. FROM employees e RIGHT JOIN departments d
  83. ON e.`department_id`=d.`department_id`;
  84. #需求:查询员工的姓名,部门名称,部门所在的城市。
  85. SELECT e.`first_name`,d.`department_name`,l.`city`
  86. FROM employees e JOIN departments d
  87. ON e.`department_id`=d.`department_id`
  88. JOIN locations l
  89. ON d.`location_id`=l.`location_id`;

$02[DML(下)] - 图1

第二章.单行函数

1.单行函数的定义

  • 操作数据对象
  • 接受参数返回一个结果
  • 只对一行进行变换
  • 每行返回一个结果
  • 可以嵌套
  • 参数可以是一列或一个值

2.字符函数

  1. /*
  2. LOWER('SQL Course') :将所有的字母变成小写
  3. UPPER('SQL Course') :将所有的字母变成大写
  4. */
  5. SELECT LOWER('AaBc');
  6. SELECT UPPER('AaBc');
  7. SELECT LOWER(first_name),UPPER(last_name)
  8. FROM employees;
  9. /*
  10. CONCAT('Hello', 'World') : 字符串拼接
  11. SUBSTR('HelloWorld',1,5) : 截取子串
  12. 1 :指的是索引位置(索引从1开始)
  13. 5 :指的是长度(偏移量)
  14. LENGTH('HelloWorld') :字符串长度
  15. INSTR('HelloWorld', 'W') : W字符在当前字符串中首次出现的位置
  16. 注意:索引位置从1开始
  17. LPAD(salary,10,'*') :向右对齐
  18. 10 : 指的是内容的长度如果不够用指定的字符补齐
  19. '*' : 用来补内容的字符
  20. RPAD(salary, 10, '*') :向左对齐
  21. 10 : 指的是内容的长度如果不够用指定的字符补齐
  22. '*' : 用来补内容的字符
  23. TRIM('H' FROM 'HelloWorld') :指定去除字符串两端的字符
  24. REPLACE('abcd','b','m') : 替换字符串所有的指定字符
  25. */
  26. SELECT REPLACE('abcaaa','a','A');
  27. SELECT TRIM('H' FROM 'HHHHHh HHH aHHHHHH');
  28. SELECT LPAD(salary,10,' '),RPAD(salary,10,' ')
  29. FROM employees;
  30. SELECT CONCAT('hello','longge');
  31. SELECT CONCAT(first_name,last_name)
  32. FROM employees;
  33. SELECT SUBSTR('hellolong',3,3);
  34. SELECT LENGTH('hello');
  35. SELECT INSTR('heollo','o');

3.数字函数

  1. /*
  2. ROUND: 四舍五入
  3. ROUND(45.926, 2) 45.93
  4. TRUNCATE: 截断
  5. TRUNCATE(45.926) 45
  6. MOD: 求余
  7. MOD(1600, 300) 100
  8. */
  9. SELECT ROUND(45.926,2), #45.93
  10. ROUND(45.926,1), #45.9
  11. ROUND(45.926,0), #46
  12. ROUND(45.926,-1);#50
  13. SELECT TRUNCATE(45.926,2), #45.92
  14. TRUNCATE(45.926,1), #45.9
  15. TRUNCATE(45.926,0), #45
  16. TRUNCATE(45.926,-1);#40
  17. #正负和被模数(第一个参数)的正负有关。
  18. SELECT MOD(4,3),MOD(-4,3),MOD(4,-3),MOD(-4,-3);

4.日期函数

  1. #日期函数
  2. SELECT NOW();
  3. #查看Mysql版本
  4. SELECT VERSION();

5.通用函数

  1. /*
  2. 通用函数 :ifnull(字段名,值) : 如果字段的内容为null就返回指定的值
  3. */
  4. #需求:获取所有人的薪水(工资+奖金)
  5. SELECT salary+salary* IFNULL(commission_pct,0),commission_pct
  6. FROM employees;

6.case表达式

  1. /*
  2. case表达式:
  3. 格式1:
  4. case 字段名
  5. when 匹配的内容1 then 返回值1
  6. when 匹配的内容2 then 返回值2
  7. when 匹配的内容3 then 返回值3
  8. ......
  9. else 返回值n
  10. end
  11. 格式2
  12. case
  13. when 表达式1 then 返回值1
  14. when 表达式2 then 返回值2
  15. else 返回值n
  16. end
  17. */
  18. /*
  19. 练习:查询部门号为 10, 20, 30 的员工信息, 若部门号为 10,
  20. 则打印其工资的 1.1 倍, 20 号部门, 则打印其工资的 1.2 倍,
  21. 30 号部门打印其工资的 1.3 倍数
  22. */
  23. SELECT salary,department_id,CASE department_id
  24. WHEN 10 THEN salary*1.1
  25. WHEN 20 THEN salary*1.2
  26. WHEN 30 THEN salary*1.3
  27. ELSE salary
  28. END AS new_salary
  29. FROM employees;
  30. #练习 :如果薪水大于等于1万输出"高"否则输出"低"
  31. SELECT salary,CASE
  32. WHEN salary>=10000 THEN "高"
  33. ELSE "低"
  34. END AS "h_l"
  35. FROM employees;

第三章.组函数

1.什么是分组函数?

分组函数作用于一组数据,并对一组数据返回一个值

2.组函数语法

  1. /*
  2. AVG() :求平均值
  3. SUM() :求和
  4. 注意:上面运算的数据类型只能是数值型
  5. MAX() :求最大值
  6. MIN() :求最小值
  7. COUNT() :统计数据的个数
  8. */
  9. SELECT AVG(salary),SUM(salary),MAX(salary),MIN(salary),COUNT(salary)
  10. FROM employees;
  11. /*
  12. avg() :
  13. 思考:求平均值时是否包含了null?没有包括null
  14. sum(),max(),min()在运算时都会忽略掉null值
  15. */
  16. SELECT COUNT(commission_pct)
  17. FROM employees;
  18. SELECT commission_pct
  19. FROM employees
  20. WHERE commission_pct IS NOT NULL;
  21. #注意:avg在做运算时不包括null
  22. SELECT SUM(commission_pct)/35,SUM(commission_pct/107),AVG(commission_pct)
  23. FROM employees;
  24. #sum,max,min在运算时都会忽略掉null值
  25. SELECT SUM(commission_pct),MAX(commission_pct),MIN(commission_pct)
  26. FROM employees;
  27. /*
  28. count(字段名) : 不包括null在内 --字段中的内容不为null的有多少条
  29. count(*) : 统计整张表中所有数据有多少条
  30. count(数值) : 统计整张表中所有数据有多少条比count(*)效率高
  31. */
  32. SELECT COUNT(commission_pct),COUNT(*),COUNT(1),COUNT(2)
  33. FROM employees;

第四章.分组和过滤

1.group by

  1. /*
  2. 注意:一旦select后面出现组函数,就不能再出现其它字段。
  3. 除非出现的字段也出现在group by的后面。
  4. */
  5. SELECT first_name,AVG(salary)
  6. FROM employees;
  7. /*
  8. 格式:
  9. select ......
  10. from 表名
  11. where 过滤条件
  12. group by 字段名1,字段名2.......
  13. order by ......
  14. */
  15. #需求:查询各部门中最高薪水是多少
  16. #注意:一旦select后面出现组函数,就不能再出现其它字段。
  17. # 除非出现的字段也出现在group by的后面。
  18. SELECT department_id,MAX(salary)
  19. FROM employees
  20. WHERE department_id IS NOT NULL
  21. GROUP BY department_id;
  22. #需求:查询各工种中平均薪水是多少,并按照平均薪水进行排序-降序
  23. SELECT job_id,AVG(salary) a_s
  24. FROM employees
  25. GROUP BY job_id
  26. #order by avg(salary) desc;
  27. ORDER BY a_s DESC;
  28. #需求:查询各部门中不同工种的最高薪水是多少,并按照最高薪水进行排序-降序
  29. SELECT department_id,job_id,MAX(salary)
  30. FROM employees
  31. WHERE department_id IS NOT NULL
  32. GROUP BY department_id,job_id
  33. ORDER BY MAX(salary) DESC;

2.having子句

使用having过滤分组

  • 行已经被分组
  • 使用了组函数
  • 满足Having子句中条件的分组将被显示
  1. /*
  2. having :过滤
  3. 格式:
  4. select .......
  5. from 表名
  6. where 过滤条件
  7. group by .....
  8. having 过滤条件
  9. order by ......
  10. where和having的区别?
  11. 1.where后面不能出现组函数,having后面可以出现组函数
  12. 2.where在group by的前面,having在group by的后面
  13. */
  14. #需求:求各管理者手下员工的最高薪水大于6000的管理者有哪些,
  15. SELECT manager_id,MAX(salary)
  16. FROM employees
  17. #where max(salary)>6000 #注意:where不能跟组函数。where是在group by之前执行。
  18. GROUP BY manager_id
  19. HAVING MAX(salary)>6000
  20. ORDER BY MAX(salary) DESC;
  21. #需求:求部门号为50,90,100中各员工的平均薪水
  22. #先求出各部门的平均薪水再过滤
  23. SELECT department_id,AVG(salary)
  24. FROM employees
  25. GROUP BY department_id
  26. HAVING department_id IN(50,90,100);
  27. #先过滤出50,90,100然后再进行分组---这种方式效率最高
  28. SELECT department_id,AVG(salary)
  29. FROM employees
  30. WHERE department_id IN(50,90,100)
  31. GROUP BY department_id;

第五章.子查询

1.定义

  1. 子查询 :在一个查询语句a中再嵌套另一个查询语b.
    b语句叫作子查询,a语句叫作外查询(主查询)
  2. 子查询分类 : 单行子查询 vs 多行子查询
  3. 单行子查询 :子查询的结果只有一条
    多行子查询 :子查询的结果有多条
  4. 单行子查询使用的运算符 := > >= < <= <>
  5. 多行子查询使用的运算符 : IN ANY ALL
    INT 等于列表中的任意一个
    ANY 和子查询返回的某一个值比较
    ALL 和子查询返回的所有值比较

2.使用(单行子查询)

  1. */
  2. #需求:谁的工资比 Abel 高?
  3. #第一种方式:查两次①先查出Abel的工资是多少 ②再用其它用工的薪水做对比
  4. SELECT salary
  5. FROM employees
  6. WHERE last_name='Abel'; #11000
  7. SELECT last_name,salary
  8. FROM employees
  9. WHERE salary>11000;
  10. #第二种方式:自连接
  11. SELECT e1.last_name,e1.`salary`
  12. FROM employees e1 JOIN employees e2
  13. ON e2.last_name='Abel' AND e1.`salary`>e2.salary;
  14. #第三种方式:子查询
  15. SELECT last_name,salary
  16. FROM employees
  17. WHERE salary>(
  18. SELECT salary
  19. FROM employees
  20. WHERE last_name='Abel'
  21. );
  22. #需求:题目:返回job_id与141号员工相同,salary比143号员工多的员工
  23. # 姓名,job_id 和工资
  24. #1.求出141号员工的job_id
  25. SELECT job_id
  26. FROM employees
  27. WHERE employee_id=141;#ST_CLERK
  28. #2.求出143号员工的薪水
  29. SELECT salary
  30. FROM employees
  31. WHERE employee_id=143;#2600
  32. #3.求job_id为ST_CLERK薪水比2600多的员工有哪些
  33. SELECT last_name,job_id,salary
  34. FROM employees
  35. WHERE job_id='ST_CLERK' AND salary>2600;
  36. #子查询
  37. SELECT last_name,job_id,salary
  38. FROM employees
  39. WHERE job_id=(
  40. SELECT job_id
  41. FROM employees
  42. WHERE employee_id=141
  43. ) AND salary>(
  44. SELECT salary
  45. FROM employees
  46. WHERE employee_id=143
  47. );
  48. #需求:返回公司工资最少的员工的last_name,job_id和salary
  49. #1.求最少工资
  50. SELECT MIN(salary)
  51. FROM employees;#2100
  52. #2.查询工资为2100的员工的信息last_name,job_id和salary
  53. SELECT last_name,job_id,salary
  54. FROM employees
  55. WHERE salary=2100;
  56. #子查询
  57. SELECT last_name,job_id,salary
  58. FROM employees
  59. WHERE salary=(
  60. SELECT MIN(salary)
  61. FROM employees
  62. );
  63. #需求:查询最低工资大于50号部门最低工资的部门id和其最低工资
  64. SELECT department_id,MIN(salary)
  65. FROM employees
  66. WHERE department_id IS NOT NULL
  67. GROUP BY department_id
  68. HAVING MIN(salary)>(
  69. #50号部门最低工资
  70. SELECT MIN(salary)
  71. FROM employees
  72. WHERE department_id=50
  73. );
  74. SELECT commission_pct
  75. FROM employees
  76. WHERE commission_pct > (
  77. #如果子查询结果为null那么查不出数据
  78. SELECT commission_pct
  79. FROM employees
  80. WHERE employee_id=100
  81. )

3.使用(多行子查询)

  1. /*
  2. 多行子查询使用的运算符 : IN ANY ALL
  3. INT 等于列表中的任意一个
  4. ANY 和子查询返回的某一个值比较
  5. ALL 和子查询返回的所有值比较
  6. */
  7. #需求:题目:返回其它部门中比job_id为‘IT_PROG’部门任一工资低的员工的员
  8. # 工号、姓名、job_id 以及salary
  9. SELECT employee_id,last_name,job_id,salary
  10. FROM employees
  11. WHERE job_id<>'IT_PROG' AND salary <ANY (
  12. #获取IT_PROG部门所有员工的薪水
  13. SELECT DISTINCT salary
  14. FROM employees
  15. WHERE job_id='IT_PROG'
  16. );
  17. #需求:返回其它部门中比job_id为‘IT_PROG’部门所有工资都低的员工
  18. # 的员工号、姓名、job_id 以及salary
  19. SELECT employee_id,last_name,job_id,salary
  20. FROM employees
  21. WHERE job_id<>'IT_PROG' AND salary <ALL (
  22. #获取IT_PROG部门所有员工的薪水
  23. SELECT DISTINCT salary
  24. FROM employees
  25. WHERE job_id='IT_PROG'
  26. );
  27. #去重:distinct
  28. SELECT DISTINCT salary
  29. FROM employees
  30. WHERE job_id='IT_PROG'