My SQL数据库基础知识点全面总结笔记(上)

亦凉 2023-05-22 06:59 49阅读 0赞

案例所用数据库,链接已更新应该是永久有效的:myemployees数据库,提取码 ozz9
girls数据库 提取码:xx9e

知识点(下):数据库知识点总结(下)

linux下的安装点这里: CentOS 8下安装mysql教程

MySQL基础知识总结

  • 一. 数据库的相关概念
  • 二. MySQL
  • 三. 常见命令和语法规范
  • 四. 一些基础查询(以myemployees数据库为例)DQL语言
    • 1.进阶一
      1. 进阶二
      • (1)按条件表达式筛选
      • (2)按逻辑表达式筛选
      • (3)模糊查询
      1. 进阶三:排序查询
      1. 进阶四:常见函数
      • 一、字符函数
      • 二、数学函数
      • 三、日期函数
      • 四、其他函数
      • 五、流程控制函数
      • 六、分组函数
      1. 进阶五:分组查询
      1. 进阶六:连接查询
      • (1) sql92标准
      • (2) sql99标准
      1. 进阶七:子查询
      1. 进阶八:分页查询

一. 数据库的相关概念

一、数据库的好处

  1. 可以持久化数据到本地
  2. 结构化查询

二、数据库的常见概念

  1. DB:数据库,存储数据的容器
  2. DBMS:数据库管理系统,又称为数据库软件或数据库产品,用于创建或管理DB
  3. SQL:结构化查询语言,用于和数据库通信的语言,不是某个数据库软件特有的,而是几乎所有主流的数据库软件通用的语言

三、数据库存储数据的特点

  1. 数据存放到表中,表再放到库中
  2. 一个库可以由多张表,每张表具有唯一的表名用来标识自己
  3. 表中有一个或多个列,列又称为“字段”,相当于java中“属性”
  4. 表中每一行数据,相当于java中“对象”

四、常见的数据库管理系统
mysql,oracle,db2,sqlserver

二. MySQL

一、MySQL的背景
前身属于瑞典的一家公司,MySQL AB,08年被sun公司收购,09年被oracle收购

二、MySQL优点
1.开源,免费,成本低
2.性能高,移植性好
3.体积小,便于安装

三、MySQL的 安装
属于c/s架构的软件,一般来讲安装服务端

四、MySQL服务的启动和停止
方法一:通过命令行
net start 服务名
net stop 服务名
方法二:计算机管理——服务

五、MySQL服务的登录和退出

登录:mysql -h主机名 -P端口号 -u用户名 -p密码(默认端口3306,用户root)

退出:exit或ctrl+c

三. 常见命令和语法规范

  1. show databases;//查看当前所有的数据库
  2. use+库名;//打开指定的库
  3. (只要用了use你就在那个库中了)
  4. show tables;//查看当前库所有的表
  5. show tables from 库名;//查看其他库所有的表
  6. create table 表名(
  7. 列名 列类型,
  8. 列名 列类型,
  9. ...
  10. )//创建表
  11. desc 表名;//查看表的结构
  12. 查看服务器的版本:
  13. 方式一:登录到mysql服务端
  14. select version();
  15. 方式二:没有登录到mysql服务端
  16. mysql --versionmysql --V

mysql的语法规范
1.不区分大小写,但建议关键字大写,表名、列名小写。
2.每条命令最好用分号结尾。
3.每条命令根据需要,可以进行缩进,或者换行(建议关键字放一行,要要查询的放一行)。
4.注释
单行注释:#注释文字
单行注释:— 注释文字(注意空格)
多行注释:/* 注释文字 */

四. 一些基础查询(以myemployees数据库为例)DQL语言

1.进阶一

  1. # select 查询列表 from 表名
  2. USE myemployees;
  3. #1.查询表中的单个字段
  4. SELECT last_name FROM employees;
  5. #2.查询表中的多个字段
  6. SELECT last_name,salary,email FROM employees;
  7. #3.查询表中所有字段(双击左侧)
  8. #方式一
  9. SELECT
  10. `department_id`,
  11. `department_name`,
  12. `manager_id`,
  13. `location_id`
  14. FROM
  15. employees;
  16. #方式二
  17. SELECT * FROM employees ;
  18. #4.查询常量值
  19. SELECT 100;
  20. SELECT 'john';
  21. #(不区分字符和字符串)
  22. #5.查询表达式
  23. SELECT 100%98;
  24. #6.查询函数
  25. SELECT VERSION();
  26. #7.起别名
  27. /*
  28. ①便于理解
  29. ②如果要查询的字段有重名的情况,使用别名可以区分开来
  30. */
  31. #方式一:用as
  32. SELECT 100%98 AS 结果;
  33. SELECT last_name AS 姓,first_name AS FROM employees;
  34. #方式二:空格
  35. SELECT last_name 姓,first_name FROM employees;
  36. #案例:查询salary,显示结果为output
  37. SELECT salary AS "out put" FROM employees;
  38. #8.去重
  39. #案例:查询员工表涉及到的所有部门编号
  40. SELECT DISTINCT department_id FROM employees;
  41. #9. +号的作用
  42. /*
  43. java中的+号:
  44. ①运算符:两个操作数都为数值型
  45. ②连接符:只要有一个操作数为字符串
  46. mysql中的+号:
  47. 仅仅只有一个功能:运算符
  48. select 100+90;
  49. select '123'+90; 其中一方为字符型,会试图将字符型数值转换成数值型
  50. 如果转换成功则继续加法运算
  51. select 'john'+90; 如果转换失败,则字符型数组值转换成0;
  52. select null+10;只要其中一方为null,则结果为null
  53. */
  54. #案例:查询员工名和姓连接成一个字段,并显示为 姓名
  55. SELECT CONCAT(last_name,first_name) AS 姓名 FROM employees;
  56. #10.判断是否为空
  57. #commission_pct是否为空?为空返回0
  58. SELECT
  59. IFNULL(commission_pct,0) AS 奖金率,
  60. commission_pct
  61. FROM
  62. employees;

2. 进阶二

  1. #进阶2: 条件查询
  2. 语法:
  3. select
  4. 查询列表
  5. from
  6. 表名
  7. where
  8. 筛选条件;
  9. 分类:
  10. 1.按条件表达式筛选
  11. 条件运算符: > < = != <>(不等于) >= <=
  12. 2.按逻辑表达式筛选
  13. 逻辑运算符:&& || !
  14. and or not
  15. 作用:连接条件表达式
  16. 3.模糊查询
  17. like
  18. between and
  19. in
  20. is null

(1)按条件表达式筛选

  1. */
  2. #1. 按条件表达式筛选
  3. #案例1:查询工资>12000的员工信息
  4. SELECT
  5. *
  6. FROM
  7. employees
  8. WHERE
  9. salary>12000;
  10. #案例2:查询部门编号不等于90号的员工名和部门编号
  11. SELECT
  12. last_name,
  13. department_id
  14. FROM
  15. employees
  16. WHERE
  17. department_id!=90;

(2)按逻辑表达式筛选

  1. #2.按逻辑表达式筛选
  2. #案例1:查询工资在10000到20000之间的员工名,工资和奖金
  3. SELECT
  4. last_name,
  5. salary,
  6. commission_pct
  7. FROM
  8. employees
  9. WHERE
  10. salary>=10000 AND salary<=20000;
  11. #案例2:查询部门编号不在90-110之间,或者工资高于15000的员工信息
  12. SELECT
  13. *
  14. FROM
  15. employees
  16. WHERE
  17. department_id<90 OR department_id>110 OR salary>15000;

(3)模糊查询

  1. #3.模糊查询
  2. /*
  3. like:
  4. ①一般和通配符搭配使用
  5. 通配符:
  6. % 任意多个字符,包含0个
  7. _ 任意单个字符
  8. */
  9. #案例1:查询员工名中包含字符a的员工信息
  10. SELECT
  11. *
  12. FROM
  13. employees
  14. WHERE
  15. last_name LIKE '%a%';
  16. #%代表通配符,代表任意个字符
  17. #案例2:查询员工名中第3个字符为n,第五个字符为l的员工名和工资
  18. SELECT
  19. last_name,
  20. salary
  21. FROM
  22. employees
  23. WHERE
  24. last_name LIKE '__n_l%';
  25. #案例3:查询员工名中第二个字符为_的员工名(转义字符)
  26. SELECT
  27. last_name
  28. FROM
  29. employees
  30. WHERE
  31. last_name LIKE '_\_%';
  32. # between and
  33. /*
  34. ①使用between and可以提高语句的简洁度
  35. ②包含临界值
  36. ③两个临界值顺序不能调换
  37. */
  38. #2.between and
  39. #案例1:查询员工编号在100到120之间的员工信息
  40. SELECT
  41. *
  42. FROM
  43. employees
  44. WHERE
  45. employee_id BETWEEN 100 AND 120;
  46. #3.in
  47. /*
  48. 含义:用于判断某字段的值是否属于in列表中的某一项
  49. 特点:
  50. ①使用in提高语句简洁度
  51. ②in列表的值类型必须统一或者兼容
  52. ③不支持通配符
  53. */
  54. #案例:查询员工的工种编号是 IT_PROT, AD_VP, AD_PRES中的一个的员工名和工种编号
  55. SELECT
  56. last_name,
  57. job_id
  58. FROM
  59. employees
  60. WHERE
  61. job_id='IT_PROT' OR job_id='AD_VP' OR job_id='AD_VP';
  62. #-------------------------------------------------------------
  63. SELECT
  64. last_name,
  65. job_id
  66. FROM
  67. employees
  68. WHERE
  69. job_id IN ('IT_PROT' ,'AD_VP' , 'AD_VP');
  70. #4. is null(is not null)
  71. /*
  72. =或者<>不能用于判断null值
  73. */
  74. #案例1:查询没有奖金的员工名和奖金率
  75. SELECT
  76. last_name,
  77. commission_pct
  78. FROM
  79. employees
  80. WHERE
  81. commission_pct IS NULL;
  82. #安全等于 <=> is null可以换成<=> null
  83. #案例1:查询没有奖金的员工名和奖金率
  84. SELECT
  85. last_name,
  86. commission_pct
  87. FROM
  88. employees
  89. WHERE
  90. commission_pct <=> NULL;
  91. #案例12:查询工资为12000的员工信息
  92. SELECT
  93. last_name,
  94. salary
  95. FROM
  96. employees
  97. WHERE
  98. salary <=> 12000;

3. 进阶三:排序查询

  1. #进阶3:排序查询
  2. /*
  3. 引入:
  4. select * from employees;
  5. 语法:
  6. SELECT 查询列表
  7. from 表
  8. [where 筛选条件]
  9. order by 排序列表 [asc|desc]
  10. 特点:
  11. 1、asc代表升序,desc代表降序,默认不写是升序
  12. 2、order by子句中可以支持单个字段、多个字段、表达式、函数、别名
  13. 3、order by子句一般是放在查询语句的最后面,limit子句除外
  14. */
  15. #案例1:查询员工信息,要求工资从高到低排序
  16. SELECT * FROM employees ORDER BY salary DESC;
  17. SELECT * FROM employees ORDER BY salary ASC;
  18. #案例2:查询部门编号>=90的员工信息,按入职时间的先后进行排序
  19. SELECT *
  20. FROM employees
  21. WHERE department_id>=90
  22. ORDER BY hiredate ASC;
  23. #案例3:按年薪高低显示员工的信息和年薪[按表达式排序]
  24. SELECT *, salary*12*(1+IFNULL(commission_pct,0)) AS 年薪
  25. FROM employees
  26. ORDER BY salary*12*(1+IFNULL(commission_pct,0)) DESC;
  27. #案例4:按年薪高低显示员工的信息和年薪[按别名排序]
  28. SELECT *, salary*12*(1+IFNULL(commission_pct,0)) AS 年薪
  29. FROM employees
  30. ORDER BY 年薪 DESC;
  31. #案例5:按姓名的长度显示员工的姓名和工资 [按函数排序]
  32. SELECT LENGTH(last_name) AS 字节长度, last_name,salary
  33. FROM employees
  34. ORDER BY LENGTH(last_name) DESC;
  35. #案例6:查询员工信息,要求先按工资升序,再按员工编号降序 [按多个字段排序]
  36. SELECT * FROM employees
  37. ORDER BY salary ASC,employee_id DESC;
  38. #整体按工资排序,工资相同时,按员工编号降序

4. 进阶四:常见函数

  1. #进阶4:常见函数
  2. /*
  3. 概念:类似java的方法,将一组逻辑语句封装在方法体中,对外暴露方法名
  4. 好处:1、隐藏了实现细节 2、提高代码的重用性
  5. 调用:select 函数名(实参列表) [from 表(根据需要)];
  6. 特点:
  7. ①叫什么(函数名)
  8. ②干什么(功能)
  9. 分类:
  10. 1、单行函数(字符函数,数学函数,日期函数,其他函数,流程控制函数)
  11. 如concat、length、ifnull等
  12. 2、分组函数
  13. 功能:做统计使用,又称为统计函数、聚合函数、组函数
  14. 常见函数:
  15. 字符函数:length concat substr
  16. instr trim upper lower
  17. lpad rpad replace
  18. 数学函数: round ceil floor truncate mod
  19. 日期函数:now curdate curtime year month monthname
  20. day hour minute second str_to_date date_format
  21. 其他函数:version database user
  22. 控制函数: if case
  23. */

一、字符函数

  1. #1. length 获取参数值的字节个数
  2. SELECT LENGTH('john');#4
  3. SELECT LENGTH('张三丰hahaha');#15utf8一个汉字占3个字节
  4. #2. concat 拼接字符串(用下划线拼接)
  5. SELECT CONCAT(last_name,'_',first_name) FROM employees;
  6. #3. upper,lower
  7. SELECT UPPER('john');#变大写
  8. SELECT LOWER('JOHN');#变小写
  9. #示例:将姓变大写,名变小写,拼接
  10. SELECT CONCAT(UPPER(last_name),LOWER(first_name)) AS 姓名 FROM employees;
  11. #4. substr,substring
  12. #注意索引从1开始,下语句输出:和李四
  13. #截取从指定索引处后面所有字符
  14. SELECT SUBSTR('张三和李四',3) out_put;
  15. #截取从指定索引处指定字符长度的字符
  16. #下面语句输出:张三
  17. SELECT SUBSTR('张三和李四',1,2) out_put;
  18. #案例:姓名中首字符大写,其他字符小写,用_拼接,显示出来
  19. SELECT CONCAT(UPPER(SUBSTR(last_name,1,1)),'_',LOWER(SUBSTR(last_name,2))) output
  20. FROM employees;
  21. #5. instr
  22. #返回子串的起始索引,找不到返回0
  23. SELECT INSTR('杨不悔爱上了殷六侠','殷六侠') AS out_put
  24. #6、trim 去掉首尾的
  25. #输出张翠山
  26. SELECT LENGTH(TRIM(' 张翠山 ')) AS out_put;
  27. #输出张aaaa翠山
  28. SELECT TRIM('a' FROM 'aaaa张aaaa翠山aaaaaaaa') AS out_put;
  29. #7、 lpad 用指定的字符实现左填充指定长度
  30. #输出*******殷素素
  31. SELECT LPAD('殷素素',10,'*') AS out_put;
  32. #输出:殷素
  33. SELECT LPAD('殷素素',2,'*') AS out_put;
  34. #8、 rpad 用指定的字符实现右填充指定长度
  35. #输出:殷素素ababababa
  36. SELECT RPAD('殷素素',12,'ab') AS out_put;
  37. #9、replace 替换
  38. SELECT REPLACE('张无忌爱上了周芷若','周芷若','赵敏') AS out_put;

二、数学函数

  1. #round四舍五入
  2. SELECT ROUND(1.65);#2
  3. SELECT ROUND(-1.45);#-1
  4. SELECT ROUND(1.567,2);#1.57,小数点后保留2
  5. #ceil向上取整(返回>=该参数的最小整数)
  6. SELECT CEIL(-1.02);#-1
  7. SELECT CEIL(1.00);#1
  8. #floor 向下取整,返回<=该参数的最大整数
  9. SELECT FLOOR(-9.99);#-10
  10. #truncate 截断
  11. SELECT TRUNCATE(1.65,1);#1.6;
  12. #mod 取余
  13. /*
  14. mod(a,b) : a-a/b*b
  15. mod(-10,-3) : -10-(-10)/(-3)*(-3)=-1;
  16. */
  17. SELECT MOD(10,-3);#1

三、日期函数

  1. #now:返回当前系统日期加时间
  2. SELECT NOW();
  3. #curdate 返回当前系统日期,不包含时间
  4. SELECT CURDATE();
  5. #curtime() 返回当前时间,不包含日期
  6. SELECT CURTIME();
  7. #可以获取指定的部分,年,月,日,小时,分,秒
  8. SELECT YEAR(NOW()) AS 年;
  9. SELECT YEAR('1998-1-1') 年;
  10. SELECT YEAR(hiredate) FROM employees;
  11. SELECT MONTH(NOW()) 月;
  12. SELECT MONTHNAME(NOW()) 月;#显示英文月份
  13. #str_to_date 将日期格式的字符转换成指定格式的日期
  14. /*
  15. %Y 四位的年份
  16. %y 2位的年份
  17. %m 月份 (01,02,...12)
  18. %c 月份(1,2,..., 12)
  19. %d 日
  20. %H小时(24)%h(12)
  21. %i 分钟 %s秒
  22. */
  23. SELECT STR_TO_DATE('9-13-1999','%m-%d-%Y') 日期;#1999-09-13
  24. SELECT STR_TO_DATE ('2020-4-17','%Y-%c-%d') AS output;#2020-4-17
  25. #查询入职日期为1992-4-3的员工信息
  26. SELECT * FROM employees WHERE hiredate='1992-4-3';
  27. SELECT * FROM employees WHERE hiredate=STR_TO_DATE('4-3 1992','%c-%d %Y');
  28. #date_format 将日期转换成字符
  29. SELECT DATE_FORMAT(NOW(),'%y年%m月%d日') AS output;#20417
  30. #查询有奖金的员工名和入职日期(xx月/xx日 xx年)
  31. SELECT last_name,DATE_FORMAT(hiredate,'%m月/%d日 %Y年') 入职日期
  32. FROM employees
  33. WHERE commission_pct IS NOT NULL;

四、其他函数

  1. #四、其他函数
  2. SELECT VERSION();
  3. SELECT DATABASE();#查看当前库
  4. SELECT USER();

五、流程控制函数

  1. #1. if函数:if else 的效果
  2. SELECT IF(10>5,'大','小');
  3. SELECT last_name,commission_pct,IF(commission_pct IS NULL,'没奖金','有奖金') 备注
  4. FROM employees;
  5. #2.case函数的使用一: switch case的效果
  6. /*
  7. case 要判断的字段或表达式
  8. when 常量1 then要显示的值1或语句1;
  9. when 常量2 then要显示的值2或语句2;
  10. ...
  11. else 要显示的值n或语句n
  12. end
  13. (搭配select当表达式,then加一个值,或者不搭配select当语句)
  14. */
  15. /*案例:查询员工的工资:要求
  16. 部门号=30,显示的工资为1.1倍
  17. 部门号=40,显示的工资为1.2倍
  18. 部门号=50,显示的工资为1.3倍
  19. 其他部门显示原工资
  20. */
  21. SELECT salary,department_id,
  22. CASE department_id
  23. WHEN 30 THEN salary*1.1
  24. WHEN 40 THEN salary*1.2
  25. WHEN 50 THEN salary*1.3
  26. ELSE salary
  27. END AS 新工资
  28. FROM employees;
  29. #3.case函数的使用二: 类似于多重if
  30. /*
  31. case
  32. when 条件1 then 要显示的值1或语句1
  33. when 条件2 then 要显示的值2或语句2
  34. ...
  35. else 要显示的值n或语句n
  36. end
  37. *与上一种情况的不同就是case后不加表达式
  38. */
  39. #案例:查询员工的工资情况
  40. /*
  41. 如果工资>20000,显示A级别
  42. 如果工资>15000,显示B级别
  43. 如果工资>10000,显示C级别
  44. 否则显示D级别
  45. */
  46. SELECT salary,
  47. CASE
  48. WHEN salary>20000 THEN 'A'
  49. WHEN salary>15000 THEN 'B'
  50. WHEN salary>10000 THEN 'C'
  51. ELSE 'D'
  52. END AS 工资级别
  53. FROM employees;

六、分组函数

  1. #六、分组函数
  2. /*
  3. 功能:用作统计使用,又称为聚合函数或统计函数或组函数
  4. 分类:
  5. sum 求和、avg平均值、max、min、count计算个数
  6. 特点
  7. 1、sum,avg用于处理数值型
  8. max,min,count可以处于任何类型
  9. 2、以上分组函数都忽略null值
  10. 3、可以和distinct搭配实现去重
  11. 4、count函数的单独介绍
  12. 5、和分组函数一同查询的字段要求是group by后的字段
  13. */
  14. #1.简单的使用
  15. SELECT SUM(salary) FROM employees;
  16. SELECT SUM(salary) 和,ROUND(AVG(salary),2) 平均 FROM employees;
  17. SELECT MAX(salary) 最高,MIN(salary) 最低 FROM employees;
  18. SELECT MIN(salary) FROM employees;
  19. SELECT COUNT(salary) FROM employees;
  20. #2.参数支持哪些类型
  21. SELECT SUM(last_name),AVG(last_name) FROM employees;
  22. SELECT SUM(hiredate),AVG(hiredate) FROM employees;
  23. #无意义,不这样用
  24. SELECT MAX(last_name),MIN(last_name) FROM employees;
  25. SELECT MAX(hiredate),MIN(hiredate) FROM employees;
  26. #支持
  27. SELECT COUNT(last_name) FROM employees;#计算非空的值 107
  28. SELECT COUNT(commission_pct) FROM employees;#35
  29. #3、是否忽略null
  30. SELECT SUM(commission_pct),AVG(commission_pct) FROM employees;
  31. #4、和distinct搭配
  32. SELECT SUM(DISTINCT salary), SUM(salary) FROM employees;
  33. SELECT COUNT(DISTINCT salary), COUNT(salary) FROM employees;
  34. #5、count函数的详细介绍
  35. SELECT COUNT(salary) FROM employees;
  36. SELECT COUNT(*) FROM employees;#统计每一列的数目,即所有行数
  37. SELECT COUNT(1) FROM employees;#和上一语句效果一样
  38. #6、和分组函数一同查询的字段有限制
  39. SELECT AVG(salary),employee_id FROM employees;#这个员工id查出来没有意义

5. 进阶五:分组查询

  1. #进阶5:分组查询
  2. /*
  3. 语法:
  4. select 分组函数(max,min这些),列(要求出现在group by后面)
  5. from 表
  6. 【where 筛选条件】
  7. group by 分组的列表
  8. 【order by】子句
  9. 注意: 查询列表必须特殊,要求是分组函数和group by后出现的字段
  10. 特点:
  11. 1、分组查询中的筛选条件分为两类(筛选的数据源不同
  12. 数据源 位置 关键字
  13. 分组前筛选: 原始表 group by子句前面 where
  14. 分组后筛选:分组后的结果集 group by子句后面 having
  15. ①分组函数做条件,肯定是放在having子句中
  16. ②能用分组前筛选的,优先考虑用分组前筛选
  17. 2、group by子句支持单个字段分组,多个字段分组,
  18. (多个字段之间用逗号隔开无顺序要求),表达式或函数(用的较少)
  19. 3、可添加排序(放在group by后)
  20. */
  21. #简单的分组查询
  22. #案例1:查询每个工种的最高工资
  23. SELECT MAX(salary),job_id
  24. FROM employees
  25. GROUP BY job_id;
  26. #案例2:查询每个位置上的部门个数
  27. SELECT COUNT(*),location_id
  28. FROM departments
  29. GROUP BY location_id;
  30. #添加分组前筛选条件
  31. #案例1:查询邮箱中包含a字符的,每个部门的平均工资
  32. SELECT AVG(salary),department_id
  33. FROM employees
  34. WHERE email LIKE '%a%'
  35. GROUP BY department_id;
  36. #案例2:查询有奖金的每个领导手下员工的最高工资
  37. SELECT MAX(salary),manager_id
  38. FROM employees
  39. WHERE commission_pct IS NOT NULL
  40. GROUP BY manager_id;
  41. #添加分组后的筛选条件
  42. #案例1:查询哪个部门的员工个数大于2
  43. #①查询每个部门的员工个数
  44. SELECT COUNT(*),department_id
  45. FROM employees
  46. GROUP BY department_id;
  47. #②根据1的结果进行筛选
  48. SELECT COUNT(*),department_id
  49. FROM employees
  50. GROUP BY department_id
  51. HAVING COUNT(*)>2;
  52. #案例2:查询每个工种有奖金的员工的最高工资>12000的 工种编号和其最高工资
  53. #①查询每个工种有奖金的员工的最高工资
  54. SELECT MAX(salary),job_id
  55. FROM employees
  56. WHERE commission_pct IS NOT NULL
  57. GROUP BY job_id;
  58. #②根据1的结果继续筛选,最高工资>12000
  59. SELECT MAX(salary),job_id
  60. FROM employees
  61. WHERE commission_pct IS NOT NULL
  62. GROUP BY job_id
  63. HAVING MAX(salary)>12000;
  64. #案例3:查询领导编号>102的每个领导手下的最低工资>5000的领导编号
  65. #①查询领导编号>102的每个领导手下的最低工资
  66. SELECT MIN(salary),manager_id
  67. FROM employees
  68. WHERE manager_id>102
  69. GROUP BY manager_id;
  70. #②在1的基础上,最低工资>5000
  71. SELECT MIN(salary),manager_id
  72. FROM employees
  73. WHERE manager_id>102
  74. GROUP BY manager_id
  75. HAVING MIN(salary)>5000;
  76. #按表达式或函数分组
  77. #案例:按员工姓名的长度分组,查询每一组的员工个数,筛选员工个数>5的
  78. SELECT COUNT(*),LENGTH(last_name) len_name
  79. FROM employees
  80. GROUP BY len_name
  81. HAVING COUNT(*)>5;
  82. #按多个字段分组
  83. #案例:查询每个部门每个工种的员工的平均工资
  84. SELECT AVG(salary),department_id,job_id
  85. FROM employees
  86. GROUP BY department_id,job_id;
  87. #添加排序
  88. ##案例:查询每个部门每个工种的员工的平均工资,并将>10000的按高低排序
  89. SELECT AVG(salary) a,department_id,job_id
  90. FROM employees
  91. GROUP BY department_id,job_id
  92. HAVING a>10000
  93. ORDER BY AVG(salary) DESC;

6. 进阶六:连接查询

  1. #连接查询
  2. /*
  3. 含义:又称多表查询,当查询的字段来自多个表,就会用到连接查询
  4. 笛卡尔乘积现象:表1有m行,表2有n行,结果=m*n行
  5. 发生原因:没有有效的连接条件
  6. 如何避免:添加有效的连接条件
  7. 分类:
  8. 按年代分类:
  9. sql92标准:仅仅支持内连接
  10. sql99标准【推荐】:支持内连接+外连接(左外,右外)+交叉连接
  11. 按功能分类:
  12. 内连接:等值连接,非等值连接,自连接
  13. 外连接:左外连接,右外连接,全外连接
  14. 交叉连接
  15. */
  16. SELECT * FROM beauty;
  17. SELECT * FROM boys;
  18. SELECT NAME,boyName FROM boys,beauty
  19. WHERE beauty.boyfriend_id=boys.id;

(1) sql92标准

  1. #1、等值连接
  2. /*
  3. ①多表等值连接的结果为多表的交集部分
  4. ②n表连接,至少需要n-1个连接条件
  5. ③多表的顺序无要求
  6. ④一般需要为表起别名
  7. ⑤可以搭配前面介绍的所有查询子句使用,比如排序,分组,筛选
  8. */
  9. #案例1:查询女神名和对应的男神名
  10. SELECT NAME,boyName
  11. FROM boys,beauty
  12. WHERE beauty.boyfriend_id=boys.id;
  13. #案例2:查询员工名和对应的部门名
  14. SELECT last_name,department_name
  15. FROM employees,departments
  16. WHERE employees.department_id=departments.department_id;
  17. #2、为表起别名
  18. /*
  19. ①提高语句简洁度
  20. ②区分多个重名的字段
  21. ③如果为表起了别名,则查询的字段就不能用原来的表名去限定,只能用别名
  22. */
  23. #查询员工名、工种号、工种名
  24. SELECT last_name,e.job_id,job_title
  25. FROM employees AS e,jobs AS j #执行顺序是这句先
  26. WHERE e.job_id=j.`job_id`;
  27. #两个表的顺序可以调换
  28. SELECT last_name,e.job_id,j.job_title
  29. FROM jobs AS j,employees AS e
  30. WHERE e.job_id=j.`job_id`;
  31. #4、可以加筛选
  32. #案例:查询有奖金的员工名、部门名
  33. SELECT last_name,department_name,commission_pct
  34. FROM employees e,departments d
  35. WHERE e.`department_id`=d.`department_id`
  36. AND e.`commission_pct` IS NOT NULL;
  37. #案例2:查询出城市名中第二个字符为o的部门名和城市名
  38. SELECT department_name,city
  39. FROM departments d,locations l
  40. WHERE d.`location_id`=l.`location_id`
  41. AND city LIKE '_o%';
  42. #5、加分组
  43. #案例1:查询每个城市的部门个数
  44. SELECT COUNT(*) 个数,city
  45. FROM departments d,locations l
  46. WHERE d.`location_id`=l.`location_id`
  47. GROUP BY city;
  48. #案例2:查询有奖金的每个部门的部门名和部门的领导编号,和该部门的最低工资
  49. SELECT department_name,d.manager_id,MIN(salary)
  50. FROM departments d,employees e
  51. WHERE d.`department_id`=e.`department_id`
  52. AND commission_pct IS NOT NULL
  53. GROUP BY department_name;
  54. #6、加排序
  55. #案例:查询每个工种的工种名和员工个数,按员工个数降序
  56. SELECT job_title,COUNT(*)
  57. FROM employees e,jobs j
  58. WHERE e.`job_id`=j.`job_id`
  59. GROUP BY job_title
  60. ORDER BY COUNT(*) DESC;
  61. #7、实现三表连接
  62. #案例:查询员工名、部门名和所在的城市
  63. SELECT last_name,department_name,city
  64. FROM employees e,departments d,locations l
  65. WHERE e.`department_id`=d.`department_id`
  66. AND d.`location_id`=l.`location_id`;
  67. ###########################################################
  68. #2、非等值连接
  69. #案例1:查询员工的工资和工资级别
  70. #创建工资级别
  71. CREATE TABLE job_grades
  72. (grade_level VARCHAR(3),
  73. lowest_sal INT,
  74. highest_sal INT);
  75. INSERT INTO job_grades
  76. VALUES ('A',1000,2999);
  77. INSERT INTO job_grades
  78. VALUES ('B',3000,5999);
  79. INSERT INTO job_grades
  80. VALUES ('C',6000,9999);
  81. INSERT INTO job_grades
  82. VALUES ('D',10000,14999);
  83. INSERT INTO job_grades
  84. VALUES ('E',15000,24999);
  85. INSERT INTO job_grades
  86. VALUES ('F',25000,40000);
  87. #############
  88. #查询员工的工资和工资级别
  89. SELECT salary,grade_level
  90. FROM employees e,job_grades g
  91. WHERE salary BETWEEN g.`lowest_sal` AND g.`highest_sal`;
  92. #3、自连接
  93. #案例:查询员工名和上级的名称
  94. SELECT e.employee_id,e.last_name,m.employee_id,m.last_name
  95. FROM employees e,employees m
  96. WHERE e.`manager_id`=m.`employee_id`;

(2) sql99标准

  1. #二、sql99标准
  2. 语法:
  3. select 查询列表
  4. from 1 别名 【连接类型】
  5. join 2 别名 on 【连接条件】
  6. on 连接条件
  7. where 筛选条件】
  8. group by 分组】
  9. having 筛选条件】
  10. order by 排序列表】
  11. 分类:
  12. 内连接:inner
  13. 外连接:左外 left outer
  14. 右外 right outer
  15. 全外 full outer
  16. 交叉连接:cross
  17. #一)内连接
  18. /*
  19. 语法:
  20. select 查询列表
  21. from 表1 别名
  22. inner join 表2 别名
  23. on 连接条件;
  24. 分类:
  25. 等值
  26. 非等值
  27. 自连接
  28. 特点:
  29. ①添加排序、分组、筛选
  30. ②inner可以省略
  31. ③筛选条件放在where后面,连接条件放在on后面,提高分离性,便于阅读
  32. ④inner join连接和sql92语法中的等值连接效果一样,都是查询多表的交集
  33. */
  34. #1、等值连接
  35. #案例1 查询员工名,部门名
  36. SELECT last_name,department_name
  37. FROM employees e
  38. INNER JOIN departments d
  39. ON e.department_id=d.`department_id`;
  40. #案例2:查询名字中包含e的员工名和工种名(添加筛选)
  41. SELECT last_name,job_title
  42. FROM employees e
  43. INNER JOIN jobs j
  44. ON e.`job_id`=j.`job_id`
  45. WHERE e.`last_name` LIKE '%e%';
  46. #案例3:查询部门个数>3的城市名和部门个数(添加分组+筛选)
  47. SELECT city,COUNT(*) 部门个数
  48. FROM locations l
  49. INNER JOIN departments d
  50. ON d.`location_id`=l.`location_id`
  51. GROUP BY city
  52. HAVING COUNT(*)>3;
  53. #案例4:查询哪个部门的部门员工个数>3的部门名,和员工个数,并按个数进行降序
  54. SELECT COUNT(*),department_name
  55. FROM employees e
  56. INNER JOIN departments d
  57. ON e.`department_id`=d.`department_id`
  58. GROUP BY department_name
  59. HAVING COUNT(*)>3
  60. ORDER BY COUNT(*) DESC;
  61. #案例5:查询员工名、部门名、工种名,并按部门名降序(三表连接)
  62. SELECT last_name,department_name,job_title
  63. FROM employees e
  64. INNER JOIN departments d
  65. ON e.`department_id`=d.`department_id`
  66. INNER JOIN jobs j
  67. ON e.`job_id`=j.`job_id`
  68. ORDER BY department_name DESC;
  69. #2、非等值连接
  70. #查询员工的工资级别
  71. SELECT salary,grade_level
  72. FROM employees e
  73. INNER JOIN job_grades g
  74. ON e.`salary` BETWEEN g.`lowest_sal` AND g.`highest_sal`;
  75. #查询工资的个数>20的级别个数,并且按工资级别降序
  76. SELECT COUNT(*),grade_level
  77. FROM employees e
  78. INNER JOIN job_grades g
  79. ON e.`salary` BETWEEN g.`lowest_sal` AND g.`highest_sal`
  80. GROUP BY grade_level
  81. HAVING COUNT(*)>20
  82. ORDER BY grade_level DESC;
  83. #3、自连接
  84. #查询员工的名字,上级的名字
  85. SELECT e.last_name,m.last_name
  86. FROM employees e
  87. JOIN employees m
  88. ON e.`manager_id`=m.`employee_id`;
  89. #加筛选:姓名中包含字符k的员工名字、上级名字
  90. SELECT e.last_name,m.last_name
  91. FROM employees e
  92. JOIN employees m
  93. ON e.`manager_id`=m.`employee_id`
  94. WHERE e.`last_name` LIKE '%k%';
  95. #二)外连接
  96. /*
  97. 应用场景:用于查找一个表中有,另一个表中没有的记录
  98. 特点:
  99. 1、外连接的查询结果为主表中所有的记录
  100. 如果从表中有和它匹配的,则显示匹配的值
  101. 如果从表中没有和它匹配的,则显示null
  102. 外连接查询结果=内连接结果+主表中有而从表中没有的记录
  103. 2、左外连接:left jon左边的是主表
  104. 右外连接:right join右边的是主表
  105. 3、左外和右外交换两个表的顺序,可以实现同样的效果
  106. 4、全外连接=内连接结果+表1有但表2没有+表2有但表1没有
  107. */
  108. #引入:查询男朋友不在男生表的女生名
  109. #左外连接
  110. SELECT be.name,bo.*
  111. FROM beauty be
  112. LEFT OUTER JOIN boys bo
  113. ON be.boyfriend_id=bo.id
  114. WHERE bo.`id` IS NULL;
  115. #右外连接
  116. SELECT be.name,bo.*
  117. FROM boys bo
  118. RIGHT OUTER JOIN beauty be
  119. ON be.boyfriend_id=bo.id
  120. WHERE bo.`id` IS NULL;
  121. #案例1:查询哪个部门没有员工
  122. #左外
  123. SELECT d.*,e.employee_id
  124. FROM departments d
  125. LEFT OUTER JOIN employees e
  126. ON d.`department_id`=e.`department_id`
  127. WHERE e.`employee_id` IS NULL;
  128. #右外
  129. SELECT d.*,e.employee_id
  130. FROM employees e
  131. RIGHT OUTER JOIN departments d
  132. ON d.`department_id`=e.`department_id`
  133. WHERE e.`employee_id` IS NULL;
  134. #三)交叉连接(笛卡尔乘积)
  135. SELECT be.*,bo.*
  136. FROM beauty be
  137. CROSS JOIN boys bo;

练习

  1. #1、查询编号>3的女神的男朋友信息,如果有则列出,没有用null填充
  2. SELECT be.id,be.name,bo.*
  3. FROM beauty be
  4. LEFT OUTER JOIN boys bo
  5. ON be.`boyfriend_id`=bo.`id`
  6. WHERE be.id>3;
  7. #2、查询哪个城市没有部门
  8. SELECT city,d.*
  9. FROM departments d
  10. RIGHT OUTER JOIN locations l
  11. ON d.`location_id`=l.`location_id`
  12. WHERE d.`department_id` IS NULL;
  13. #3、查询部门名为SAL或IT的员工信息
  14. SELECT e.*,d.department_name
  15. FROM departments d
  16. LEFT OUTER JOIN employees e
  17. ON d.`department_id`=e.`department_id`
  18. WHERE d.`department_name`IN ('SAL' , 'IT');

7. 进阶七:子查询

  1. #进阶7:子查询
  2. 含义:出现在其他语句内部的select语句,称为子查询或内查询
  3. 外部的查询语句,称为主查询或外查询
  4. 分类:
  5. 按子查询出现的位置:
  6. select后面:仅仅支持标量子查询
  7. from后面:支持表子查询
  8. where或者having后面:标量子查询,列子查询,行子查询
  9. exists后面(相关子查询):表子查询
  10. 按结果集的行列数不同:
  11. 标量子查询(结果集只有一行一列)
  12. 列子查询(结果集只有一列多行)
  13. 行子查询(结果集有一行多列)
  14. 表子查询(结果集一般为多行多列)

(1)where或having后面

  1. #1、标量子查询
  2. #2、列子查询(多行子查询)
  3. #3、行子查询(多行多列)
  4. 特点:
  5. ①子查询放在小括号内
  6. ②子查询一般放在条件右侧
  7. ③标量子查询,一般搭配单行操作符使用
  8. > < >= <= = <>
  9. 列子查询一般搭配多行操作符使用
  10. IN/NOT INANY/SOMEALL
  11. ④子查询的执行优先于主查询执行
  12. #1、标量子查询
  13. #案例1:谁的工资比Abel高
  14. #①查询abel的工资
  15. SELECT salary
  16. FROM employees
  17. WHERE last_name='Abel';
  18. #②查询员工的信息,满足salary>①的结果
  19. SELECT *
  20. FROM employees
  21. WHERE salary>(
  22. SELECT salary
  23. FROM employees
  24. WHERE last_name='Abel'
  25. );
  26. #案例2:返回job_id与141号员工相同,salary比143号员工多的员工姓名,job_id和工资
  27. #①查询141号员工的job_id
  28. SELECT job_id
  29. FROM employees
  30. WHERE employee_id=141;
  31. #②查询143号员工的salary
  32. SELECT salary
  33. FROM employees
  34. WHERE employee_id=143;
  35. #③员工的姓名,job_id,工资,要求job_id=①并且salary>②
  36. SELECT last_name,job_id,salary
  37. FROM employees
  38. WHERE job_id=(
  39. SELECT job_id
  40. FROM employees
  41. WHERE employee_id=141
  42. ) AND salary>(
  43. SELECT salary
  44. FROM employees
  45. WHERE employee_id=143
  46. );
  47. #案例3:返回公司工资最少的员工的last_name,job_id,salary
  48. #①查询公司的最低工资
  49. SELECT MIN(salary)
  50. FROM employees
  51. #②查询last_name,job_id
  52. SELECT last_name,job_id,salary
  53. FROM employees
  54. WHERE salary=(
  55. SELECT MIN(salary)
  56. FROM employees
  57. );
  58. #案例4:查询最低工资大于50号部门的最低工资的部门id和其最低工资
  59. #①查询50号部门的最低工资
  60. SELECT MIN(salary)
  61. FROM employees
  62. WHERE department_id=50;
  63. #②查询每个部门的最低工资
  64. SELECT MIN(salary)
  65. FROM employees
  66. GROUP BY department_id;
  67. #③筛选②
  68. SELECT MIN(salary),department_id
  69. FROM employees
  70. GROUP BY department_id
  71. HAVING MIN(salary)>(
  72. SELECT MIN(salary)
  73. FROM employees
  74. WHERE department_id=50
  75. );
  76. #2、列子查询(多行子查询)
  77. #案例1:返回location_id是1400或1700的部门中所有员工姓名
  78. #①查询location_id是1400或1700的部门编号
  79. SELECT DISTINCT department_id
  80. FROM departments
  81. WHERE location_id IN(1400,1700);
  82. #②查询员工姓名要求部门号是①中的某个
  83. SELECT last_name
  84. FROM employees
  85. WHERE department_id IN(
  86. SELECT DISTINCT department_id
  87. FROM departments
  88. WHERE location_id IN(1400,1700)
  89. );#in可以换成 =ANY
  90. #案例2:返回其他工种中比job_id为‘IT_PROG'部门任一工资低的员工信息
  91. #用any相当于小于max工资
  92. SELECT employee_id,last_name,job_id,salary
  93. FROM employees
  94. WHERE salary<ANY(
  95. SELECT DISTINCT salary
  96. FROM employees
  97. WHERE job_id='IT_PROG'
  98. ) AND job_id <> 'IT_PROG';
  99. #案例3:返回其他工种中比job_id为‘IT_PROG'部门所有工资低的员工信息
  100. SELECT employee_id,last_name,job_id,salary
  101. FROM employees
  102. WHERE salary<ALL(
  103. SELECT DISTINCT salary
  104. FROM employees
  105. WHERE job_id='IT_PROG'
  106. ) AND job_id <> 'IT_PROG';
  107. #3、行子查询(结果集是一行多列或多行多列)
  108. #案例:查询员工编号最小并且工资最高的员工信息
  109. SELECT *
  110. FROM employees
  111. WHERE employee_id=(
  112. SELECT MIN(employee_id)
  113. FROM employees
  114. )
  115. AND salary=(
  116. SELECT MAX(salary)
  117. FROM employees
  118. );
  119. #或者
  120. SELECT *
  121. FROM employees
  122. WHERE (employee_id,salary)=(
  123. SELECT MIN(employee_id),MAX(salary)
  124. FROM employees
  125. );

(2)select后面

  1. /*
  2. 仅支持标量子查询
  3. */
  4. #案例1:查询每个部门的员工个数
  5. SELECT d.*,(
  6. SELECT COUNT(*)
  7. FROM employees e
  8. WHERE e.department_id=d.`department_id`
  9. )个数
  10. FROM departments d;
  11. #案例2:查询员工号=102的部门名
  12. SELECT (
  13. SELECT department_name
  14. FROM departments d
  15. INNER JOIN employees e
  16. ON d.department_id=e.department_id
  17. WHERE e.employee_id=102
  18. );

(3)from后面

  1. #案例:查询每个部门的平均工资的工资等级
  2. #①查询每个部门的平均工资
  3. SELECT AVG(salary),department_id
  4. FROM employees
  5. GROUP BY department_id
  6. #②连接①的结果集和等级表,筛选条件 平均工资between最低和最高
  7. SELECT ag_dep.*,g.grade_level
  8. FROM(
  9. SELECT AVG(salary) ag,department_id
  10. FROM employees
  11. GROUP BY department_id
  12. ) ag_dep
  13. INNER JOIN job_grades g
  14. ON ag_dep.ag BETWEEN g.lowest_sal AND g.highest_sal;

(4)exists后面(相关子查询)

  1. /*
  2. exists完整的查询语句
  3. 结果:1或0
  4. */
  5. SELECT EXISTS(SELECT employee_id FROM employees);#结果为1,表示存在
  6. #案例1:查询有员工的部门名
  7. SELECT department_name
  8. FROM departments d
  9. WHERE d.`department_id` IN(
  10. SELECT department_id
  11. FROM employees
  12. );
  13. #或
  14. SELECT department_name
  15. FROM departments d
  16. WHERE EXISTS(
  17. SELECT *
  18. FROM employees e
  19. WHERE e.`department_id`=d.`department_id`
  20. );
  21. #案例2:查询没有女朋友的男生信息
  22. #in
  23. SELECT bo.*
  24. FROM boys bo
  25. WHERE bo.id NOT IN(
  26. SELECT boyfriend_id
  27. FROM beauty
  28. );
  29. #exists
  30. SELECT bo.*
  31. FROM boys bo
  32. WHERE NOT EXISTS(
  33. SELECT boyfriend_id
  34. FROM beauty be
  35. WHERE bo.`id`=be.`boyfriend_id`
  36. );

相关练习

  1. #1.查询和Zlotkey相同部门的员工姓名和工资
  2. SELECT last_name,salary
  3. FROM employees
  4. WHERE department_id=(
  5. SELECT department_id
  6. FROM employees
  7. WHERE last_name='Zlotkey'
  8. );
  9. #2、查询工资比公司平均工资高的员工的员工号,姓名,工资
  10. SELECT last_name,employee_id,salary
  11. FROM employees
  12. WHERE salary>(
  13. SELECT AVG(salary)
  14. FROM employees
  15. );
  16. #3、查询各部门中工资比本部门平均工资高的员工号,姓名,工资
  17. SELECT employee_id,last_name,salary,e.`department_id`
  18. FROM employees e
  19. INNER JOIN(
  20. SELECT AVG(salary) ag,department_id
  21. FROM employees
  22. GROUP BY department_id
  23. )avg_dep
  24. ON e.`department_id`=avg_dep.department_id
  25. WHERE salary>avg_dep.ag;
  26. #4、查询,和姓名中包含字母u的员工在相同部门的员工,的员工号和姓名
  27. SELECT last_name,employees_id
  28. FROM employees
  29. WHERE department_id IN(
  30. SELECT DISTINCT department_id
  31. FROM employees
  32. WHERE last_name LIKE '%u%'
  33. );
  34. #5、查询在部门的location id为1700的部门工作的员工的员工号
  35. SELECT employee_id
  36. FROM employees
  37. WHERE department_id=ANY(
  38. SELECT department_id
  39. FROM departments
  40. WHERE location_id=1700
  41. );
  42. #6、查询管理者是king的员工姓名和工资
  43. SELECT last_name,salary
  44. FROM employees
  45. WHERE manager_id IN(
  46. SELECT employee_id
  47. FROM employees
  48. WHERE last_name='K_ing'
  49. );
  50. #7、查询工资最高的员工的姓名,要求first和last_name显示为一列,列名为姓名
  51. SELECT CONCAT(first_name,last_name) "姓名"
  52. FROM employees
  53. WHERE salary=(
  54. SELECT MAX(salary)
  55. FROM employees
  56. );

8. 进阶八:分页查询

  1. 应用场景:当要显示的数据一页显示不全,需要分页提交sql请求
  2. 语法:
  3. select 查询列表
  4. from
  5. join type join 2
  6. where 筛选条件
  7. group by 分组字段
  8. having 分组后的筛选
  9. order by 排序的字段】
  10. limit offsetsize;
  11. offset:要显示条目的起始索引,起始索引从0开始
  12. size:要显示的条目数
  13. 特点:
  14. limit语句放在查询语句的最后
  15. ②公式
  16. 要显示的页数 page,每页的条目数size
  17. select 查询列表
  18. from
  19. limit (page-1)*size,size;
  20. #案例1:查询前五条员工信息
  21. SELECT * FROM employees LIMIT 0,5;
  22. SELECT * FROM employees LIMIT 5;
  23. #案例2:查询第11条——第25条
  24. SELECT * FROM employees LIMIT 10,15;
  25. #案例3:有奖金的员工信息,并且工资较高的前10名显示
  26. SELECT * FROM employees
  27. WHERE commission_pct IS NOT NULL
  28. ORDER BY salary DESC
  29. LIMIT 10;

发表评论

表情:
评论列表 (有 0 条评论,49人围观)

还没有评论,来说两句吧...

相关阅读