多表查询,数据库事务(附:部门员工多表查询案例)

多表查询 、数据库事务 –> 面试重点(概念,三个步骤,四个特征)

一 多表查询 —-> 难点

1、笛卡尔积
    A.语法: 
        SELECT * FROM 表名称1,表名称2;
    B.查询出来的数据条目数:
        a.计算公式
            表名称1的条目数x表名称2的条目数 
        b.例如: 
            表1有4条,表2里面9条. 查询的结果是 4*9 = 36 条
2、内连接查询
    A.隐式内连接 语法
        SELECT * FROM 表1,表2 WHERE 表1.列1 = 表2.列2;  -- 标准写法
        SELECT * FROM 表1 别名1,表2 别名2 WHERE 别名1.列1 = 别名2.列2;  -- 别名的写法 
    B.显式内连接 语法
        SELECT * FROM 表1 INNER JOIN 表2 ON 表1.列1 = 表2.列2; -- 完整格式
        SELECT * FROM 表1 JOIN 表2 ON  表1.列1 = 表2.列2; -- 省略INNER的格式
    C.内连接查询的结果
        a.特点:
            两个表当中交集的部分.取数据多的。
            表1,有8条数据,6条数据在交集当中.
            表2,有20条数据,10条数据在交集当中.
            那么采用内连接查询的结果是 10 条数据。
        b.两个表内连接查询的时候,
            表1有10条数据,表2有5条数据.请问.最多有多少条数据,最少有多少条数据?
            最多10条,最少0条。
3、外连接查询
    A.左外连接
        a.语法格式
            SELECT * FROM 表1 LEFT OUTER JOIN 表2 ON 表1.列1 = 表2.列2; -- 完整格式
            SELECT * FROM 表1 LEFT JOIN 表2 ON  表1.列1 = 表2.列2; -- 省略OUTER的格式
        b.结果特点
            左表的全部内容+左右表的交集。(JOIN的左边就是左表,JOIN的右边就是右表) 
    B.右外连接
        a.语法格式
            SELECT * FROM 表1 RIGHT OUTER JOIN 表2 ON 表1.列1 = 表2.列2; -- 完整格式
            SELECT * FROM 表1 RIGHT JOIN 表2 ON  表1.列1 = 表2.列2; -- 省略OUTER的格式
        b.结果特点
            右表的全部内容+左右表的交集。(JOIN的左边就是左表,JOIN的右边就是右表) 
    C.思考问题
        两个表左外连接查询的时候,
            表1有5条数据,表2有10条数据.请问.最多有多少条数据,最少有多少条数据?
            左表是 表1,右表是 表2
            最多14条,最少5条。
4、子查询
    A.概念
        子查询,也可以理解为"嵌套查询".一个查询语句的结果是下一个查询语句的条件.
    B.子查询的情况
        a.单行单列,主要采用> < >= <= = <> 判断
            案例: 
                查询最高工资的员工信息
                原始做法:
                    SELECT MAX(gongzi) FROM yuangong;  -- 查询到最高的员工工资
                    SELECT * FROM yuangong WHERE gongzi = 查询到的结果;  -- 查询到的最高工资作为条件.再查询他信息
                子查询的情况  
                    SELECT * FROM yuangong WHERE gongzi = (SELECT MAX(gongzi) FROM yuangong);
        b.多行单列,主要采用的 IN(选项1,选项2,选项3)
            案例:
                查询财务部和市场部的员工信息
                原始做法:
                    SELECT id FROM yuangong WHERE name IN ('财务部','市场部'); -- 查询到财务部和市场部的ID
                    SELECT * FROM yuangong WHERE id = 查询到的id结果; -- 通过查询到的结果作为条件,查询满足条件的所有员工信息
                子查询的情况
                    SELECT * FROM yuangong WHERE id IN (SELECT id FROM yuangong WHERE name IN ('财务部','市场部')); 
        c.多行多列,作为虚拟表,进行的连接查询.
            案例:
                查询入职日期是2011-11-11日之后的员工信息和部门信息
                子查询的情况
                    SELECT * FROM bumen t1 ,(SELECT * FROM yuangong WHERE yuangong.join_date > '2011-11-11') t2 WHERE t1.id = t2.bumen_id;
                采用普通内连接
                    SELECT * FROM bumen t1 , yuangong t2  WHERE  t1.id = t2.bumen_id AND t2.join_date > '2011-11-11';
5、多表查询的分析思路:
    A.确定查询的表  FROM 表名称...
    B.查询的条件 WHERE  条件...  ---> 需要查看表结构(主外键) 大小...
    C.查询的结果 SELECT 结果...

二 数据库事务 –> 面试重点

1、事务的概念
    在多个操作的SQL语句当中,要么同时成功执行,要么同时失败执行。
2、操作步骤:
    A.开启事务  START TRANSACTION
    B.回滚(出问题了,需要回到开启事务之前)       ROLLBACK
    C.提交(正常执行,将改变的数据提交结束事务) COMMIT
3、查看和修改事务的提交方式
    A.查看事务的提交方式
        SELECT @@autocommit;
    B.修改事务的提交方式
        SET @@autocommit = 0;  -- 0表示手动提交,1表示自动提交
4、事务的四大特征
    A.原子性: 在事务的多个SQL语句当中,不可以分割开来
    B.持久性: 发生回滚和提交的时候,数据持久的保存在硬盘上面
    C.隔离性: 尽可能的多个事务之间没有影响
    D.一致性: 事务前后的总量不能改变
5、隔离级别
    A.存在问题
        a.脏读:事务X读取到事务Y,未提交的数据.
        b.虚读(不可重复读):在同一个事务当中,两次读取的数据不一样。
        c.幻读:事务X在操作数据库当中所有的记录,事务Y在添加一条新的记录。事务X读取不到自己的修改
    B.对应的级别
        a. READ UNCOMMITED 读未提交 (出现"脏读","虚读","幻读")
        b. READ COMMITED  读提交 (出现"虚读","幻读")  ---> Oracle 默认采用
        c. REPEATABLE READ 可重复读 (出现"幻读") ---> MySQL 默认采用
        d. SERIALIZABLE 串行化 (可以解决所有问题,效率低)
    C.设置和查看隔离级别
        a.查看隔离级别
            SELECT @@TX_ISOLATION;
        b.设置隔离级别
            SET GLOBAL TRANSACTION ISOLATION LEVEL 级别字符串;

三 DCL管理用户

1、创建用户(账号密码)
    语法: CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';  -- 主机名 本机 localhost 任意主机 %
2、删除用户(账号)
    语法: DROP USER '用户名'@'主机名';
3、修改用户密码
    语法1: UPDATE USER SET PASSWORD = PASSWORD('新密码') WHERE USER = '用户名';
    语法2: SET PASSWORD FOR '用户名'@'主机名' = PASSWORD('新密码');
4、查询用户(账号密码)
    语法: USE mysql;  SELECT * FROM user;  -- 先要使用mysql自己的数据库,然后查询user表
5、忘记了超级管理员用户密码之后的解决方案:
    a. cmd 输入 net stop mysql  -- 停止mysql服务 需要管理员运行该cmd
    b. 使用无验证方式启动mysql服务: mysqld --skip-grant-tables
    c. 打开新的cmd窗口,直接输入mysql命令,敲回车。就可以登录成功
    d. use mysql;
    e. update user set password = password('你的新密码') where user = 'root';
    f. 关闭两个窗口
    g. 打开任务管理器,手动结束mysqld.exe 的进程
    h. 启动mysql服务
    i. 使用新密码登录。
6、数据库权限
    A.查询权限
        语法: SHOW GRANTS FOR '用户名'@'主机名';
    B.授予权限
        语法: GRANT 权限列表 ON 数据库名.表名 TO '用户名'@'主机名';  -- 标准格式
        语法: GRANT ALL ON *.* TO 'zhangsan'@'localhost';  -- 给张三本机用户授予所有的权限
    C.撤销权限
        语法: REVOKE 权限列表 ON 数据库名.表名 FROM '用户名'@'主机名';
        案例: REVOKE UPDATE ON db3.`account` FROM 'lisi'@'%';  -- 撤销李四在所有机器上面的 UPDATE 权限

部门员工案例

这里写图片描述

– 部门表

CREATE TABLE DEPT(
DEPTNO INT PRIMARY KEY,
DNAME VARCHAR(14), -- 部门名称
LOC VARCHAR(13)-- 部门地址
) ; 

INSERT INTO DEPT VALUES (10,'ACCOUNTING','NEW YORK');
INSERT INTO DEPT VALUES (20,'RESEARCH','DALLAS');
INSERT INTO DEPT VALUES (30,'SALES','CHICAGO');
INSERT INTO DEPT VALUES (40,'OPERATIONS','BOSTON');

SELECT * FROM DEPT;

– 员工表

CREATE TABLE EMP(
EMPNO INT  PRIMARY KEY, -- 员工编号
ENAME VARCHAR(10), -- 员工姓名
JOB VARCHAR(9), -- 员工工作
MGR INT, -- 员工直属领导编号
HIREDATE DATE, -- 入职时间
SAL DOUBLE, -- 工资
COMM DOUBLE, -- 奖金
DEPTNO INT,  -- 所在部门
FOREIGN KEY (DEPTNO) REFERENCES DEPT(DEPTNO));  -- 关联dept表  

-- ALTER TABLE EMP ADD FOREIGN KEY (DEPTNO) REFERENCES DEPT(DEPTNO);
INSERT INTO EMP VALUES(7369,'SMITH','职员',7566,"1980-12-17",800,NULL,20);
INSERT INTO EMP VALUES(7499,'ALLEN','销售员',7698,'1981-02-20',1600,300,30);
INSERT INTO EMP VALUES(7521,'WARD','销售员',7698,'1981-02-22',1250,500,30);
INSERT INTO EMP VALUES(7566,'JONES','经理',7839,'1981-04-02',2975,NULL,20);
INSERT INTO EMP VALUES(7654,'MARTIN','销售员',7698,'1981-09-28',1250,1400,30);
INSERT INTO EMP VALUES(7698,'BLAKE','经理',7839,'1981-05-01',2850,NULL,30);
INSERT INTO EMP VALUES(7782,'CLARK','经理',7839,'1981-06-09',2450,NULL,10);
INSERT INTO EMP VALUES(7788,'SCOTT','职员',7566,'1987-07-03',3000,2000,20);
INSERT INTO EMP VALUES(7839,'KING','董事长',NULL,'1981-11-17',5000,NULL,10);
INSERT INTO EMP VALUES(7844,'TURNERS','销售员',7698,'1981-09-08',1500,50,30);
INSERT INTO EMP VALUES(7876,'ADAMS','职员',7566,'1987-07-13',1100,NULL,20);
INSERT INTO EMP VALUES(7900,'JAMES','职员',7698,'1981-12-03',1250,NULL,30);
INSERT INTO EMP VALUES(7902,'FORD','销售员',7566,'1981-12-03',3000,NULL,20);
INSERT INTO EMP VALUES(7934,'MILLER','职员',7782,'1981-01-23',1300,NULL,10);

SELECT * FROM EMP;

– 工资等级表

CREATE TABLE SALGRADE( 
GRADE INT,-- 等级
LOSAL DOUBLE, -- 最低工资
HISAL DOUBLE ); -- 最高工资

INSERT INTO SALGRADE VALUES (1,500,1000);
INSERT INTO SALGRADE VALUES (2,1001,1500);
INSERT INTO SALGRADE VALUES (3,1501,2000);
INSERT INTO SALGRADE VALUES (4,2001,3000);
INSERT INTO SALGRADE VALUES (5,3001,9999);

SELECT * FROM SALGRADE;

单表操作练习

1、查找部门30中员工的详细信息。
select * from emp where deptno = 30;

  2、找出从事职员工作的员工的编号、姓名、部门号。
  select empno,ename,deptno from emp where job = '职员';

  3、检索出奖金多于基本工资的员工信息。
  select * from emp where comm>sal;

  4、检索出奖金多于基本工资60%的员工信息。
 select * from emp where comm>sal*0.6;

  5、找出姓名中包含A的员工信息。
 select * from emp where Ename like '%A%';

  6、找出姓名以A、B、S开始的员工信息。
 select * from emp where Ename like 'A%' or ename like  'B%' or ename like 'S%';

  7、找到名字长度为7个字符的员工信息。
    select * from emp where length(ename)=7;

  8、名字中不包含R字符的员工信息。
    select * from emp where ename not like '%r%';

  9、返回员工的详细信息并按姓名升序排序。
 select * from emp order by ename asc;

  10、返回员工的信息并按姓名降序,工资升序排列。
 select * from emp order by ename desc ,sal asc;

  11、计算员工的日薪(按30天)。
select ename,sal/30 from emp ;

  12、找出获得奖金的员工的信息。
SELECT * FROM emp WHERE IFNULL(comm,0)>0;
SELECT * FROM emp WHERE comm IS NOT NULL;

  13、找出奖金少于100或者没有获得奖金的员工的信息。
select * from emp where comm<100 or comm is null;

  14、找出10部门的经理、20部门的职员 的员工信息。
select * from emp where  job = '经理' and deptno = 10 or job = '职员'and deptno = 20;

  15、找出10部门的经理、20部门的职员 或者既不是经理也不是职员但是工资高于2000元的员工信息
select * from emp where  job = '经理' and deptno = 10 or job = '职员'and deptno = 20 or job not in('经理','职员') and sal>2000;

多表操作练习

  1、返回部门号及其本部门的最低工资。
    select deptno ,min(sal)from emp group by deptno;

  2、计算出员工的年薪,并且以年薪排序。
select*, sal*12 as allsal from emp order by  allsal asc;

  3、返回员工工作及其从事此工作的最低工资。
 select job,min(sal) from emp group by job;

  4、查找和scott从事相同工作的员工信息
select * from emp where job = (select job from emp where ename =  'scott');

  5、工资水平多于james的员工信息。
 select * from emp where sal > (select sal from emp where ename = 'james');

  6、返回工资大于平均工资的员工信息。
select * from emp where sal > (select avg(sal) from emp);

  7、返回销售部(sales)所有员工的姓名。
select ename from emp where deptno = ( select deptno from dept where dname = 'sales');

  8、返回工资高于30部门所有员工工资水平的员工信息。
select * from emp where sal > all(select sal from emp where deptno=30);

  9、返回查找最高工资和最低工资的职员信息
 select emp.* from emp,(select min(sal) min_sal, max(sal) max_sal from emp where job='职员') sal where emp.job='职员' and (emp.sal=sal.min_sal or emp.sal=sal.max_sal);


  10、返回拥有员工的部门名、部门号。
select distinct dept.deptno,dept.dname from dept inner join emp on dept.deptno=emp.deptno 

  11、返回员工的姓名、所在部门名及其工资。
select emp.ename,dept.dname,emp.sal from emp,dept where emp.deptno=dept.deptno;

  12、返回从事职员工作的员工姓名和所在部门名称。
 select emp.ename,dept.dname from emp,dept where emp.deptno=dept.deptno and emp.job ='职员';

  13、返回部门号、部门名、部门所在位置及其每个部门的员工总数。   
select dept.deptno,dept.dname,dept.loc ,count(*)from dept,emp where dept.deptno=emp.deptno group by dept.deptno;
  14、返回员工(职员或者销售员)和所属经理的姓名。
select * from emp where job in('职员','销售员');
select * from emp where job='经理';
select e1.ename,e2.ename from emp e1,(select empno,ename from emp where job='经理') e2 where e1.mgr=e2.empno;

  15、返回员工(职员或者销售员)的入职日期早于其经理入职日期的员工及其经理姓名。
    select empno,ename,hiredate from emp where job='经理';
select e1.ename,e2.ename, from emp e1,(select empno,ename,hiredate from emp where job='经理') e2 where e1.mgr=e2.empno and e1.hiredate<e2.hiredate;


  16、返回工资处于第四级别的员工的姓名和工资。
select emp.ename,emp.sal from emp,(select losal,hisal from salgrade where grade=4) salgrade where emp.sal between salgrade.losal and salgrade.hisal;

猜你喜欢

转载自blog.csdn.net/qq_43113232/article/details/82426156