1、多表查询

多表查询概述:

同时查询多张表获取需要的数据,组成完整的信息返回给用户

多表查询语法:

  1. select
  2. 字段列表
  3. from
  4. 表名列表
  5. where
  6. 条件列表
  7. group by
  8. 分组字段
  9. having
  10. 分组之后的条件
  11. order by
  12. 排序
  13. limit
  14. 分页

多表查询分类:

笛卡尔积:

多张表的记录进行结合,这种现象被称之为笛卡尔积(交叉连接)

  1. select ... from 左表 右表 ;
  2. example1:
  3. select * from biao1,biao2;
  4. example2:
  5. select count(*) from biao1,biao2;

内连接:

拿左表的记录去匹配右表的记录,若符合条件显示(两张表的交集)

  1. -- 隐式内连接
  2. select ... from 左表,右表 where 连接条件;
  3. -- 显示内连接【推荐,不知道为啥,反正就推荐】
  4. select ... from 左表 [inner] join 右表 on 连接条件;

外连接:

外连接又分为左外连接和右外连接
意思就是如果是左外连接就显示左边表的全部记录,显示右边表符合条件的记录,其余为null
右外连接反之,显示右边表的全部,左边的符合条件的就显示,其余也为null

  1. select ... from 左表 left [outer] join 右表 on 连接条件;【推荐】
  2. select ... from 左表 right [outer] join 右表 on 连接条件;

子查询:

一条select语句执行结果,作为另一条select语法的一部分,其实就是select语句的嵌套!

2、多表查询案例

  1. -- 创建数据库db3
  2. CREATE DATABASE db3;
  3. -- 使用db3
  4. USE db3;
  5. -- 创建相关表
  6. -- 多表案例
  7. -- 部门表
  8. CREATE TABLE dept (
  9. id INT PRIMARY KEY AUTO_INCREMENT, -- 部门id
  10. dname VARCHAR(50), -- 部门名称
  11. loc VARCHAR(50) -- 部门位置
  12. );
  13. -- 添加4个部门
  14. INSERT INTO dept(id,dname,loc) VALUES
  15. (10,'教研部','北京'),
  16. (20,'学工部','上海'),
  17. (30,'销售部','广州'),
  18. (40,'财务部','深圳');
  19. -- 职务表
  20. CREATE TABLE job (
  21. id INT PRIMARY KEY,
  22. jname VARCHAR(20), -- 职务名称
  23. description VARCHAR(50) -- 职务描述
  24. );
  25. -- 添加4个职务
  26. INSERT INTO job (id, jname, description) VALUES
  27. (1, '董事长', '管理整个公司,接单'),
  28. (2, '经理', '管理部门员工'),
  29. (3, '销售员', '向客人推销产品'),
  30. (4, '文员', '使用办公软件');
  31. -- 员工表
  32. CREATE TABLE emp (
  33. id INT PRIMARY KEY, -- 员工id
  34. ename VARCHAR(50), -- 员工姓名
  35. job_id INT, -- 职务id 外键
  36. mgr INT , -- 上级领导
  37. joindate DATE, -- 入职日期
  38. salary DECIMAL(7,2), -- 工资 99999.99
  39. bonus DECIMAL(7,2), -- 奖金 99999.99
  40. dept_id INT, -- 所在部门编号 外键
  41. CONSTRAINT emp_jobid_ref_job_id_fk FOREIGN KEY (job_id) REFERENCES job (id),
  42. CONSTRAINT emp_deptid_ref_dept_id_fk FOREIGN KEY (dept_id) REFERENCES dept (id)
  43. );
  44. -- 添加员工
  45. INSERT INTO emp(id,ename,job_id,mgr,joindate,salary,bonus,dept_id) VALUES
  46. (1001,'孙悟空',4,1004,'2000-12-17','8000.00',NULL,20),
  47. (1002,'卢俊义',3,1006,'2001-02-20','16000.00','3000.00',30),
  48. (1003,'林冲',3,1006,'2001-02-22','12500.00','5000.00',30),
  49. (1004,'唐僧',2,1009,'2001-04-02','29750.00',NULL,20),
  50. (1005,'李逵',4,1006,'2001-09-28','12500.00','14000.00',30),
  51. (1006,'宋江',2,1009,'2001-05-01','28500.00',NULL,30),
  52. (1007,'刘备',2,1009,'2001-09-01','24500.00',NULL,10),
  53. (1008,'猪八戒',4,1004,'2007-04-19','30000.00',NULL,20),
  54. (1009,'罗贯中',1,NULL,'2001-11-17','50000.00',NULL,10),
  55. (1010,'吴用',3,1006,'2001-09-08','15000.00','0.00',30),
  56. (1011,'沙僧',4,1004,'2007-05-23','11000.00',NULL,20),
  57. (1012,'李逵',4,1006,'2001-12-03','9500.00',NULL,30),
  58. (1013,'小白龙',4,1004,'2001-12-03','30000.00',NULL,20),
  59. (1014,'关羽',4,1007,'2002-01-23','13000.00',NULL,10);
  60. -- 工资等级表
  61. CREATE TABLE salarygrade (
  62. grade INT PRIMARY KEY, -- 等级
  63. losalary INT, -- 最低工资
  64. hisalary INT -- 最高工资
  65. );
  66. -- 添加5个工资等级
  67. INSERT INTO salarygrade(grade,losalary,hisalary) VALUES
  68. (1,7000,12000),
  69. (2,12010,14000),
  70. (3,14010,20000),
  71. (4,20010,30000),
  72. (5,30010,99990);
  73. -- 案例练习:
  74. /*
  75. 案例一
  76. 查询所有的员工信息,显示员公编号,员工姓名,工资,职务名称,职务描述
  77. */
  78. SELECT
  79. e.id, #员工编号
  80. e.ename, #员工姓名
  81. e.salary, #员工工资
  82. j.jname, #职务名称
  83. j.description #职务描述
  84. FROM
  85. emp AS e, #员工表
  86. job AS j #职务表
  87. WHERE
  88. e.job_id = j.id; #当员工表中的职务id外键等于职务表中的主键时
  89. /*
  90. 案例二
  91. 查询所有的员工信息,显示员工编号,员工姓名,工资,职务名称,职务描述,部门名称,部门位置
  92. */
  93. SELECT
  94. e.id,
  95. e.ename,
  96. e.salary,
  97. j.jname,
  98. j.description,
  99. d.dname,
  100. d.loc
  101. FROM
  102. emp e,
  103. job j,
  104. dept d
  105. WHERE
  106. e.job_id = j.id AND e.dept_id = d.id ;
  107. /*
  108. 案例三
  109. 查询员工的姓名,工资,工资等级
  110. */
  111. SELECT
  112. e.ename,
  113. e.salary,
  114. s.grade
  115. FROM
  116. emp e,
  117. salarygrade s
  118. WHERE
  119. e.salary BETWEEN s.losalary AND s.hisalary #员工表中的工资跟等级表中的数值范围作比较
  120. ORDER BY grade DESC; #按照工资等级降序显示
  121. /*
  122. 案例四
  123. 查询员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级
  124. */
  125. SELECT
  126. e.ename AS '员工姓名',
  127. e.salary AS '员工工资',
  128. j.jname AS '职务名称',
  129. j.description AS '职务描述',
  130. d.dname AS '部门名称',
  131. d.loc AS '部门描述',
  132. s.grade AS '工资等级'
  133. FROM
  134. emp e,
  135. job j,
  136. dept d,
  137. salarygrade s
  138. WHERE
  139. e.job_id = j.id AND
  140. e.dept_id = d.id AND
  141. e.salary BETWEEN s.losalary AND s.hisalary;
  142. /*
  143. 案例五
  144. 查询出部门编号,部门名称,部门位置,部门人数
  145. */
  146. -- 先根据员工表 统计部门数和每个部门的人数
  147. SELECT dept_id,COUNT(id) FROM emp GROUP BY dept_id;
  148. -- 统计部门表
  149. SELECT
  150. d.id,
  151. d.dname,
  152. d.loc,
  153. e.num #由员工表统计的个部门的具体人数
  154. FROM
  155. dept d,
  156. (SELECT dept_id,COUNT(id) AS num FROM emp GROUP BY dept_id) e
  157. WHERE
  158. d.id = e.dept_id;
  159. -- PS:查询出来的一个表,可作为一个具体的表参与后续的查询操作
  160. /*
  161. 案例六
  162. 查询每个员工的名称及其上级领导的名称
  163. */
  164. -- 方法一 缺点:如果一个员工没有上级领导的话,则不会显示出来
  165. SELECT
  166. yuangong.id '员工编号',
  167. yuangong.ename '员工姓名',
  168. yuangong.mgr '上级领导编号',
  169. lingdao.ename '上级领导姓名'
  170. FROM
  171. emp yuangong,
  172. emp lingdao
  173. WHERE
  174. yuangong.mgr = lingdao.id;
  175. -- 方法二
  176. SELECT
  177. yuangong.id,
  178. yuangong.ename,
  179. lingdao.id,
  180. lingdao.ename
  181. FROM
  182. emp yuangong
  183. LEFT OUTER JOIN
  184. emp lingdao
  185. ON
  186. yuangong.mgr = lingdao.id;

3、用户权限DCL

接触不到,个人了解
做到大佬的境界自然而然就会了

4、事务

如果一个包含多个步骤的业务操作,被事务管理,那么这些个操作要么同时成功,要么同时失败
案例:用户转账操作

事务的操作步骤:

1、开启事务:begin / start transaction
2、回滚:rollback
3、提交:commit
如果事务的所有操作都成功那么提交,要是某一个失败则回滚。

事务的提交方式:

自动提交:
mysql就是自动提交的,一条DML语句会自动提交一次
手动提交:
Oracle数据库默认是手动提交事务,需要先开启事务,再提交

修改事务的提交方式:

查看事务的提交方式:
select @@autocommit;1:代表自动提交 0:代表手动提交
show variables like ‘autocommit’; NO:代表自动提交 OFF:代表手动提交
修改默认提交方式:改成手动提交
set @@autocommit = 0 ;
set autocommit = off ;

事务的四大特征(ACID)

1、原子性(Atomicity):是不可分割的最小操作单位,要么同时成功,要么同时失败
2、一致性(Consistency):事务操作前后,保证数据的一致性
3、隔离性(Isolation):多个事务之间,相互独立,互不干扰
4、持久性(Durability):当事务提交或回滚后,数据库会持久化的保存数据

事务的隔离性:

多个事务之间的隔离性,相互独立的,但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题
1、脏读:一个事务,读取到另一个事务中没有提交的数据
2、不可重复读(虚读):在同一个事务中,两次读取到的数据不一样
3、幻读:一个事务操作数据表中的所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改

| 级别 | 名字 | 隔离级别 | 脏读 | 不可重复读 | 幻读 | 数据库默认隔离级别 | | 1 | 读未提交 | read uncommitted | 是 | 是 | 是 | | | —- | —- | —- | —- | —- | —- | —- | | 2 | 读已提交 | read committed | 否 | 是 | 是 | Oracle和SQL Server | | 3 | 可重复读 | repeatable read | 否 | 否 | 是 | MySQL | | 4 | 串行化 | serializable | 否 | 否 | 否 | |

PS:隔离级别从小到大安全性越来越高,但是效率越来越低
查询当前数据库的隔离级别:
show variables like ‘%isolation’ ;
临时修改隔离级别:
set session transaction isolation level 级别字符串 ;