• Mysql之库、表、记录相关操作4


    Mysql之库、表、记录相关操作4

    多表数据

    create table dep(
    	id int primary key auto_increment,
    	name varchar(16),
    	work varchar(16)
    );
    create table emp(
    	id int primary key auto_increment,
    	name varchar(16),
    	salary float,
    	dep_id int
    );
    insert into dep values(1, '市场部', '销售'), (2, '教学部', '授课'), (3, '管理部', '开车');
    insert into emp(name, salary, dep_id) values('egon', 3.0, 2),('yanghuhu', 2.0, 2),('sanjiang', 10.0, 1),('owen', 88888.0, 2),('liujie', 8.0, 1),('yingjie', 1.2, 0);
    

    多表查询

    一、交叉连接-笛卡尔积

    ​ 交叉连接不匹配任何条件

    '''
    # 需求: 
    # 查看每位员工的部门的所有信息
    select * from emp;
    select * from dep;
    
    # 子查询, 最终结果只能显示单表的信息, 但需求是同时显示两张表的信息 => 先将两张表合成一张表
    select * from emp where dep_id in (select id from dep);
    
    '''
    '''
    笛卡尔积: 集合 X{a, b} * Y{o, p, q} => Z{{a, o}, {a, p}, {a, q}, {b, o}, {b, p}, {b, q}}
    交叉查询: select * from emp, dep; | select * from emp course join dep;
    '''
    
    ''' 做了筛选, 结果<=完整数据, 非笛卡尔积
    select * from emp, dep where db2.emp.dep_id = db2.dep.id;  # 同sql语句上表现是从两张表拿数据
    # 注意: 同时查询两张表形成新的表,可以称之为虚拟表, 原表与表之间可能存在重复字段, 同时使用时需要明确所属表,必要时还需明确所属数据库
    '''
    

    二、内连接

    ​ 内连接:只连接匹配的行

    ​ 找两张表共有的部分,相当于利用条件从笛卡尔积结果中筛选出了正确的结果

    '''
    inner join on
    
    内连接:结果为两张表有对应关系的数据(emp有dep没有,emp没有dep有的记录均不会被虚拟表展示)
    
    语法:左表 inner join 右表 on 两表有关联的字段的条件, on就是产生对于关系的(连接的依据)
    
    eg:select * from emp inner join dep on emp.dep_id = dep.id;
    '''
    

    三、外连接之左连接

    ​ 左连接:优先显示左表的全部记录

    ​ 以左表为准,本质就是在内连接的基础上增加左边有右边没有的结果

    '''
    left join on
    左连接:在内连接的基础上还保留左表特有的记录
    语法:左表 left join 右表 on 两表有关联的字段的条件
    eg:select emp.name '员工', dep.name '部门', dep.work '职责' from emp left join dep on emp.dep_id = dep.id;
    '''
    

    四、外连接之右连接

    ​ 右连接:优先显示右表全部记录

    ​ 以右表为准,本质就是在内连接的基础上增加右边有左边没有的结果

    '''
    right join on
    右连接:在内连接的基础上还保留右表特有的记录
    语法:左表 right join 右表 on 两表有关联的字段的条件
    eg:select * from emp right join dep on emp.dep_id = dep.id;
    '''
    
    '''
    在连接语法join 前就是左表, 后就是右表
    采用的是left关键词就是左连接, right关键词就是右连接, inner关键词就是内连接
    '''
    

    五、全外连接

    ​ 全外连接:显示左右两个表的全部记录

    注:MySQL不支持圈外连接full JOIN

    '''
    全连接:在内连接的基础上分别保留这左表及右表特有的记录
    语法:mysql没有full join on语法,但可以通过去重达到效果
    eg:
    select * from emp left join dep on emp.dep_id = dep.id
    union
    select * from emp right join dep on emp.dep_id = dep.id;
    '''
    注意:union 与union all的区别 :union 会去掉相同的记录
    mysql> select * from emp left join dep on emp.dep_id = dep.id union all select * from emp right join dep on emp.dep_id = dep.id;
    +------+----------+--------+--------+------+-----------+--------+
    | id   | name     | salary | dep_id | id   | name      | work   |
    +------+----------+--------+--------+------+-----------+--------+
    |    3 | sanjiang |     10 |      1 |    1 | 市场部    | 销售   |
    |    5 | liujie   |      8 |      1 |    1 | 市场部    | 销售   |
    |    1 | egon     |      3 |      2 |    2 | 教学部    | 授课   |
    |    2 | yanghuhu |      2 |      2 |    2 | 教学部    | 授课   |
    |    4 | owen     |  88888 |      2 |    2 | 教学部    | 授课   |
    |    6 | yingjie  |    1.2 |      0 | NULL | NULL      | NULL   |
    |    1 | egon     |      3 |      2 |    2 | 教学部    | 授课   |
    |    2 | yanghuhu |      2 |      2 |    2 | 教学部    | 授课   |
    |    3 | sanjiang |     10 |      1 |    1 | 市场部    | 销售   |
    |    4 | owen     |  88888 |      2 |    2 | 教学部    | 授课   |
    |    5 | liujie   |      8 |      1 |    1 | 市场部    | 销售   |
    | NULL | NULL     |   NULL |   NULL |    3 | 管理部    | 开车   |
    +------+----------+--------+--------+------+-----------+--------+
    12 rows in set (0.00 sec)
    
    mysql> select * from emp left join dep on emp.dep_id = dep.id union select * from emp right join dep on emp.dep_id = dep.id;
    +------+----------+--------+--------+------+-----------+--------+
    | id   | name     | salary | dep_id | id   | name      | work   |
    +------+----------+--------+--------+------+-----------+--------+
    |    3 | sanjiang |     10 |      1 |    1 | 市场部    | 销售   |
    |    5 | liujie   |      8 |      1 |    1 | 市场部    | 销售   |
    |    1 | egon     |      3 |      2 |    2 | 教学部    | 授课   |
    |    2 | yanghuhu |      2 |      2 |    2 | 教学部    | 授课   |
    |    4 | owen     |  88888 |      2 |    2 | 教学部    | 授课   |
    |    6 | yingjie  |    1.2 |      0 | NULL | NULL      | NULL   |
    | NULL | NULL     |   NULL |   NULL |    3 | 管理部    | 开车   |
    +------+----------+--------+--------+------+-----------+--------+
    7 rows in set (0.00 sec)
    

    练习:

    '''
    1.查询每一位员工对应的工作职责
    # 每一位员工 => 左表为emp表, 那么左表的所有数据均需要被保留, 所有采用左连接
    		   => 左表为dep表, 那么右表的所有数据均需要被保留, 所有采用右连接
    # select emp.name, dep.work from emp left join dep on emp.dep_id = dep.id;
    select emp.name, dep.work from dep right join emp on emp.dep_id = dep.id;
    
    2.查询每一个部门下的员工们及员工职责
    # select max(dep.name), max(dep.work), group_concat(emp.name) from emp right join dep on emp.dep_id = dep.id group by dep_id;
    
    # 分析过程
    # 每一个部门 => dep的信息要被全部保留, 需要分组
    # 员工职责 => dep.work, 由于分组不能直接被查询 => 需要用聚合函数处理
    # 员工们 => emp.name做拼接 => group_concat(emp.name)
    # 分组的字段 => 部门 => emp.dep_id => emp.dep_id可以直接被查询,但没有显示意义 => dep.name用来显示 => dep.name需要用聚合函数处理
    
    
    select max(dep.name), max(dep.work), group_concat(emp.name) from dep left join emp on  emp.dep_id = dep.id group by emp.dep_id;
    
    # 注: on在where条件关键词之左
    '''
    
  • 相关阅读:
    面向对象方法与调用
    LeetCode OJ:Spiral Matrix(螺旋矩阵)
    LeetCode OJ:Jump Game(跳跃游戏)
    LeetCode OJ:Word Search(单词查找)
    LeetCode OJ:Majority Element II(主元素II)
    LeetCode OJ:Maximum Subarray(子数组最大值)
    LeetCode OJ:Next Permutation(下一排列)
    LeetCode OJ:Product of Array Except Self(除己之外的元素乘积)
    LeetCode OJ:Remove Duplicates from Sorted Array II(移除数组中的重复元素II)
    LeetCode OJ:Best Time to Buy and Sell Stock II(股票买入卖出最佳实际II)
  • 原文地址:https://www.cnblogs.com/prodigal/p/10256838.html
Copyright © 2020-2023  润新知