MySQL二

MySQL

多表查询

查询语法:select 列名列表 from 表名列表 where...

准备sql

-- 创建班级表
    CREATE TABLE class(
        id INT PRIMARY KEY AUTO_INCREMENT,
        `name` VARCHAR(20)
        );

INSERT INTO class(`name`)  VALUES (信息安全),(移动通信),(计算机科学);

SELECT * FROM class;

CREATE TABLE student (
        id INT PRIMARY KEY AUTO_INCREMENT,
        NAME VARCHAR(10),
        gender CHAR(1), -- 性别
        score DOUBLE, -- 分数
        join_date DATE, -- 上学日期
        class_id INT,
        FOREIGN KEY (class_id) REFERENCES class(id) -- 外键,关联课程表(课程表的主键)
    );

    INSERT INTO student(NAME,gender,score,join_date,class_id) VALUES(孙悟空,,73,2013-02-24,1);
    INSERT INTO student(NAME,gender,score,join_date,class_id) VALUES(猪八戒,,90,2010-12-02,2);
    INSERT INTO student(NAME,gender,score,join_date,class_id) VALUES(唐僧,,89,2008-08-08,2);
    INSERT INTO student(NAME,gender,score,join_date,class_id) VALUES(白骨精,,68,2015-10-07,3);
    INSERT INTO student(NAME,gender,score,join_date,class_id) VALUES(蜘蛛精,,63,2011-03-14,1);
SELECT * FROM student;

MySQL二

 

 MySQL二

 

 笛卡尔积:

有两个集合A,B .取这两个集合的所有组成情况。
要完成多表查询,需要消除无用的数据

 

多表查询分类:

1. 内连接查询:

1、隐式内连接:使用where消除无用的数据

-- 查询所有学生信息和对应的班级信息

SELECT * FROM student,class WHERE class.`id`=student.`class_id`;

-- 查询学生表的名称,性别。班级表的名称
SELECT 
student.`NAME`,
student.`gender`,
class.`name` 
FROM 
student,class 
WHERE student.`class_id`=class.`id`;

2. 显式内连接:

语法:select 字段列表 from 表1 left [outer] join 表2 on 条件;

SELECT * FROM student INNER JOIN class ON student.`class_id` = class.`id`;
SELECT * FROM student JOIN class ON student.`class_id` = class.`id`;
-- INNER可以省略

2、外连接查询

 

1、左外连接

语法:select 字段列表 from 表1 left【outer】join 表2 on 条件

查询的是左表所有数据以及其交集部分。

-- 查询所有学生信息,如果学生有班级,则查询班级名称,没有班级,则不显示班级名称
SELECT
s1.*,
c2.`name`
FROM
student s1 LEFT JOIN class c2 ON s1.`class_id` = c2.`id`

2、右外连接

语法:select 字段列表 from 表1 right【outer】 join 表2 on 条件

查询的是右表所有数据以及其交集部分。

SELECT     * FROM class t2 RIGHT OUTER JOIN student t1 ON t1.`class_id` = t2.`id`;

3、子查询

查询中嵌套查询

-- 查询分数最高的学生信息

-- 查询分数最高的学生信息
SELECT MAX(score) FROM student;

-- 查询学生信息,并且分数等于90的
SELECT * FROM student WHERE student.`score`=90;

-- 合并为一条SQL
SELECT * FROM student WHERE student.`score`=(SELECT MAX(score) FROM student);

 

-- 查询学生平均分小于平均分的学生

select * from student where student.score < (select avg(score) from
student);

-- 子查询可以作为条件,使用运算符in来判断

SELECT id FROM class WHERE NAME = 信息安全 OR NAME = 移动通信 ;

SELECT * FROM student WHERE class_id = 2 OR class_id = 1;

SELECT * FROM student WHERE class_id IN (SELECT id FROM class WHERE NAME = 信息安全 OR NAME = 移动通信 
);
-- 查询学生上学日期是2011-11-11日之后的学生信息和班级信息

SELECT * FROM class c1,(SELECT * FROM student WHERE student.`join_date`>2011-11-11) s2
WHERE c1.`id`=s2.class_id;

-- 普通内连接
SELECT * FROM student s1,class c2 WHERE s1.`class_id`= c2.`id` AND s1.`join_date` > 2011-11-11

4、多表练习

-- 部门表
            CREATE TABLE dept (
              id INT PRIMARY KEY PRIMARY KEY, -- 部门id
              dname VARCHAR(50), -- 部门名称
              loc VARCHAR(50) -- 部门所在地
            );

-- 添加4个部门
            INSERT INTO dept(id,dname,loc) VALUES 
            (10,教研部,北京),
            (20,学工部,上海),
            (30,销售部,广州),
            (40,财务部,深圳);

-- 职务表,职务名称,职务描述
                CREATE TABLE job (
                  id INT PRIMARY KEY,
                  jname VARCHAR(20),
                  description VARCHAR(50)
                );


-- 添加4个职务
            INSERT INTO job (id, jname, description) VALUES
            (1, 董事长, 管理整个公司,接单),
            (2, 经理, 管理部门员工),
            (3, 销售员, 向客人推销产品),
            (4, 文员, 使用办公软件);

-- 员工表
                CREATE TABLE emp (
                  id INT PRIMARY KEY, -- 员工id
                  ename VARCHAR(50), -- 员工姓名
                  job_id INT, -- 职务id
                  mgr INT , -- 上级领导
                  joindate DATE, -- 入职日期
                  salary DECIMAL(7,2), -- 工资
                  bonus DECIMAL(7,2), -- 奖金
                  dept_id INT, -- 所在部门编号
                  CONSTRAINT emp_jobid_ref_job_id_fk FOREIGN KEY (job_id) REFERENCES job (id),
                  CONSTRAINT emp_deptid_ref_dept_id_fk FOREIGN KEY (dept_id) REFERENCES dept (id)
                );



-- 添加员工
            INSERT INTO emp(id,ename,job_id,mgr,joindate,salary,bonus,dept_id) VALUES 
            (1001,孙悟空,4,1004,2000-12-17,8000.00,NULL,20),
            (1002,卢俊义,3,1006,2001-02-20,16000.00,3000.00,30),
            (1003,林冲,3,1006,2001-02-22,12500.00,5000.00,30),
            (1004,唐僧,2,1009,2001-04-02,29750.00,NULL,20),
            (1005,李逵,4,1006,2001-09-28,12500.00,14000.00,30),
            (1006,宋江,2,1009,2001-05-01,28500.00,NULL,30),
            (1007,刘备,2,1009,2001-09-01,24500.00,NULL,10),
            (1008,猪八戒,4,1004,2007-04-19,30000.00,NULL,20),
            (1009,罗贯中,1,NULL,2001-11-17,50000.00,NULL,10),
            (1010,吴用,3,1006,2001-09-08,15000.00,0.00,30),
            (1011,沙僧,4,1004,2007-05-23,11000.00,NULL,20),
            (1012,李逵,4,1006,2001-12-03,9500.00,NULL,30),
            (1013,小白龙,4,1004,2001-12-03,30000.00,NULL,20),
            (1014,关羽,4,1007,2002-01-23,13000.00,NULL,10);
-- 工资等级表
                CREATE TABLE salarygrade (
                  grade INT PRIMARY KEY,   -- 级别
                  losalary INT,  -- 最低工资
                  hisalary INT -- 最高工资
                );
-- 添加5个工资等级
            INSERT INTO salarygrade(grade,losalary,hisalary) VALUES 
            (1,7000,12000),
            (2,12010,14000),
            (3,14010,20000),
            (4,20010,30000),
            (5,30010,99990);
-- 1.查询所有员工信息。查询员工编号,员工姓名,工资,职务名称,职务描述

SELECT 
    e1.`id`, -- 员工编号
    e1.`ename`, -- 员工姓名
    e1.`salary`,-- 工资
    j1.`jname`, -- 职务名称
    j1.`description` -- 职务描述
        FROM 
    emp e1, job j1
        WHERE 
    e1.`job_id` = j1.`id`;
    
-- 2.查询员工编号,员工姓名,工资,职务名称,职务描述,部门名称,部门位置

SELECT
    e1.`id`,
    e1.`ename`,
    e1.`salary`,
    j1.`jname`,
    j1.`description`,
    d1.`dname`,
    d1.`loc`
FROM
    emp e1,job j1,dept d1
WHERE e1.`dept_id`=d1.`id` AND e1.`job_id`=j1.`id` 

-- 3.查询员工姓名,工资,工资等级

SELECT 
    e1.`ename`,
    e1.`salary`,
    s1.*
FROM
    emp e1,salarygrade s1
WHERE e1.`salary` BETWEEN s1.`losalary` AND s1.`hisalary`;

-- 4.查询员工姓名,工资,职务名称,职务描述,部门名称,部门位置,工资等级
-- emp job dept salarygrade
-- emp.job_id = job.id and emp.dept_id =dept.id and 
-- emp.salary BETWEEN salarygrade.losalary and salarygrade.hisalary

SELECT 
    e1.`ename`,
    e1.`salary`,
    j1.`jname`,
    j1.`description`,
    d1.`dname`,
    d1.`loc`,
    s1.`grade`    
FROM
    emp e1,job j1,dept d1,salarygrade s1
WHERE
    e1.`job_id` = j1.`id` 
    AND e1.`dept_id` =d1.`id` 
    AND e1.`salary` BETWEEN s1.`losalary` AND s1.`hisalary`

-- 5.查询出部门编号、部门名称、部门位置、部门人数
-- dept emp
SELECT dept_id,COUNT(id) total FROM emp GROUP BY dept_id; 
 
 SELECT 
    d1.`id`,d1.`dname`,d1.`loc` , e1.total
 FROM
    dept d1,
    (SELECT dept_id,COUNT(id) total FROM emp GROUP BY dept_id
) e1

WHERE d1.`id` = e1.dept_id

-- 6.查询所有员工的姓名及其直接上级的姓名,没有领导的员工也需要查询

SELECT 
    e1.`ename`,
    e1.`mgr`,
    e2.`id`,
    e2.`ename`
FROM 
    emp e1
LEFT JOIN emp e2
ON e1.`mgr` =e2.`id`;

 

5、事务

1、概念:如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败

2、操作:

  1.开启事务:start transaction;

  2.回滚:rollback;(执行出现问题)

  3.提交:commit;(执行没有问题)

3、事务提交的两种方式:

  自动提交:MySQL

  手动提交:Oracle

4、 修改事务的默认提交方式:

  SELECT @@autocommit;(1代表自动提交,0代表手动提交)

  set @@autocommit = 0;

 

事务的四大特性:

1、原子性:表示不可分割的最小操作单位,要么同时成功,要么同时失败

2、持久性:当事务提交或回滚后,数据库将持久化保存数据

3、隔离性:多个事务之间是相互独立的

4、一致性:事务操作前后,数据总量保持不变

事务隔离级别:

虽然多个事务之间是隔离且相互独立的,但当多个事务同时操作同一数据时,会引发一些问题,此时我们就需要设置不同的隔离级别来解决

存在的问题:

  1、脏读:一个事务读取到另一个事务没有提交的数据

  2、不可重复读:在同一事务中,两次读取到的数据不一致

  3、幻读:一个事务操作(DML)数据表中所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改。

隔离级别:

  读未提交:read uncommitted(脏读,不可重复读,幻读)1

  读已提交:read committed(不可重复读,幻读)(Orcal)  2

  可重复读:repeatable read(幻读)(MySQL)       3

  串行化:serializable(安全性最高,效率最低)           4(隔离级别)

  set global transaction isolation level 隔离级别(read uncommitted)---设置隔离级别

  

DCL:数据控制语言

 DCL:管理用户,授权

1、用户管理

USE mysql;
SELECT * FROM USER; -- 查看用户
CREATE USER demo@localhost IDENTIFIED BY 123; -- 添加用户
UPDATE USER SET PASSWORD = PASSWORD(1234)WHERE USER = demo;
SET PASSWORD FOR demo@localhost =PASSWORD(abc); -- 修改用户密码
-- mysql中忘记了root用户的密码?使用无验证方式启动mysql服务: mysqld --skip-grant-tables

2、权限管理

SHOW GRANTS FOR root@localhost; -- 查询权限
SHOW GRANTS FOR lisi@%;-- % 表示可以在任意主机使用用户登录数据库
-- grant 权限列表 on 数据库名.表名 to ‘用户名‘@‘主机名‘;
GRANT ALL ON *.* TO zhangsan@localhost; -- 授予权限,任意数据库任意表
REVOKE UPDATE ON db3.`account` FROM lisi@%;-- 撤销权限 revoke 权限列表 on 数据库名.表名 from ‘用户名‘@‘主机名‘;

 

MySQL二

上一篇:jQuery事件(五)


下一篇:.NET 5 部署在docker上运行