zoukankan      html  css  js  c++  java
  • 数据库之多表查询

    阅读目录

    一、介绍

    文章内容:

    • 多表连接查询
    • 复合条件连接查询
    • 子查询

    准备表和记录

    #建表
    create table dep(
    id int,
    name varchar(20) 
    );
    
    create table emp(
    id int primary key auto_increment,
    name varchar(20),
    sex enum('male','female') not null default 'male',
    age int,
    dep_id int
    );
    
    #插入数据
    insert into dep values
    (200,'技术'),
    (201,'人力资源'),
    (202,'销售'),
    (203,'运营')
    (205,'美工'); insert into emp(name,sex,age,dep_id) values (
    'jason','male',18,200), ('egon','female',48,201), ('kevin','male',18,201), ('nick','male',28,202), ('owen','male',18,203), ('jerry','female',18,204);

    二、多表连接查询

    #重点:外链接语法
    
    SELECT 字段列表
        FROM 表1 INNER|LEFT|RIGHT|union JOIN 表2
        ON 表1.字段 = 表2.字段;
    """
        inner join  内连接
        left join   左连接
        right join  右连接
        union       全连接
    """

    交叉连接,不适用于任何匹配条件,生成笛卡尔积

    mysql> select * from dep,emp;     # 结果   笛卡尔积,是把员工表中的每条记录和部门表中的每条记录映射一遍
    +------+--------------+----+-------+--------+------+--------+
    | id   | name         | id | name  | sex    | age  | dep_id |
    +------+--------------+----+-------+--------+------+--------+
    |  200 | 技术         |  1 | jason | male   |   18 |    200 |
    |  201 | 人力资源     |  1 | jason | male   |   18 |    200 |
    |  202 | 销售         |  1 | jason | male   |   18 |    200 |
    |  203 | 运营         |  1 | jason | male   |   18 |    200 |
    |  200 | 技术         |  2 | egon  | female |   48 |    201 |
    |  201 | 人力资源     |  2 | egon  | female |   48 |    201 |
    |  202 | 销售         |  2 | egon  | female |   48 |    201 |
    |  203 | 运营         |  2 | egon  | female |   48 |    201 |
    |  200 | 技术         |  3 | kevin | male   |   18 |    201 |
    |  201 | 人力资源     |  3 | kevin | male   |   18 |    201 |
    |  202 | 销售         |  3 | kevin | male   |   18 |    201 |
    |  203 | 运营         |  3 | kevin | male   |   18 |    201 |
    |  200 | 技术         |  4 | nick  | male   |   28 |    202 |
    |  201 | 人力资源     |  4 | nick  | male   |   28 |    202 |
    |  202 | 销售         |  4 | nick  | male   |   28 |    202 |
    |  203 | 运营         |  4 | nick  | male   |   28 |    202 |
    |  200 | 技术         |  5 | owen  | male   |   18 |    203 |
    |  201 | 人力资源     |  5 | owen  | male   |   18 |    203 |
    |  202 | 销售         |  5 | owen  | male   |   18 |    203 |
    |  203 | 运营         |  5 | owen  | male   |   18 |    203 |
    |  200 | 技术         |  6 | jerry | female |   18 |    204 |
    |  201 | 人力资源     |  6 | jerry | female |   18 |    204 |
    |  202 | 销售         |  6 | jerry | female |   18 |    204 |
    |  203 | 运营         |  6 | jerry | female |   18 |    204 |
    +------+--------------+----+-------+--------+------+--------+
    24 rows in set (0.00 sec)
    
    mysql>
    #那如何low的得到两个表拼接的内容
    mysql> select * from emp,dep where emp.dep_id = dep.id;
    +----+-------+--------+------+--------+------+--------------+
    | id | name  | sex    | age  | dep_id | id   | name         |
    +----+-------+--------+------+--------+------+--------------+
    |  1 | jason | male   |   18 |    200 |  200 | 技术         |
    |  2 | egon  | female |   48 |    201 |  201 | 人力资源     |
    |  3 | kevin | male   |   18 |    201 |  201 | 人力资源     |
    |  4 | nick  | male   |   28 |    202 |  202 | 销售         |
    |  5 | owen  | male   |   18 |    203 |  203 | 运营         |
    +----+-------+--------+------+--------+------+--------------+
    5 rows in set (0.00 sec)
    
    mysql>

    inner join内连接:只连接匹配的行

    # 只拼接两张表中公有的数据部分

    mysql> select * from emp inner join dep on emp.dep_id = dep.id;
    +----+-------+--------+------+--------+------+--------------+
    | id | name  | sex    | age  | dep_id | id   | name         |
    +----+-------+--------+------+--------+------+--------------+
    |  1 | jason | male   |   18 |    200 |  200 | 技术         |
    |  2 | egon  | female |   48 |    201 |  201 | 人力资源     |
    |  3 | kevin | male   |   18 |    201 |  201 | 人力资源     |
    |  4 | nick  | male   |   28 |    202 |  202 | 销售         |
    |  5 | owen  | male   |   18 |    203 |  203 | 运营         |
    +----+-------+--------+------+--------+------+--------------+
    5 rows in set (0.00 sec)
    
    mysql> 

    left join左连接:优先显示左表全部记录

    # 左表所有的数据都展示出来 没有对应的项就用NULL

    mysql> select * from emp left join dep on emp.dep_id = dep.id;
    +----+-------+--------+------+--------+------+--------------+
    | id | name  | sex    | age  | dep_id | id   | name         |
    +----+-------+--------+------+--------+------+--------------+
    |  1 | jason | male   |   18 |    200 |  200 | 技术         |
    |  2 | egon  | female |   48 |    201 |  201 | 人力资源     |
    |  3 | kevin | male   |   18 |    201 |  201 | 人力资源     |
    |  4 | nick  | male   |   28 |    202 |  202 | 销售         |
    |  5 | owen  | male   |   18 |    203 |  203 | 运营         |
    |  6 | jerry | female |   18 |    204 | NULL | NULL         |
    +----+-------+--------+------+--------+------+--------------+
    6 rows in set (0.00 sec)
    
    mysql>

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

    # 右表所有的数据都展示出来 没有对应的项就用NULL

    mysql> select * from emp right join dep on emp.dep_id = dep.id;
    +------+-------+--------+------+--------+------+--------------+
    | id   | name  | sex    | age  | dep_id | id   | name         |
    +------+-------+--------+------+--------+------+--------------+
    |    1 | jason | male   |   18 |    200 |  200 | 技术         |
    |    2 | egon  | female |   48 |    201 |  201 | 人力资源     |
    |    3 | kevin | male   |   18 |    201 |  201 | 人力资源     |
    |    4 | nick  | male   |   28 |    202 |  202 | 销售         |
    |    5 | owen  | male   |   18 |    203 |  203 | 运营         |
    | NULL | NULL  | NULL   | NULL |   NULL |  205 | 美工         |
    +------+-------+--------+------+--------+------+--------------+
    6 rows in set (0.00 sec)
    
    mysql> 

    union:全连接 左右两表所有的数据都展示出来

    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;

    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  | sex    | age  | dep_id | id   | name         |
    +------+-------+--------+------+--------+------+--------------+
    |    1 | jason | male   |   18 |    200 |  200 | 技术         |
    |    2 | egon  | female |   48 |    201 |  201 | 人力资源     |
    |    3 | kevin | male   |   18 |    201 |  201 | 人力资源     |
    |    4 | nick  | male   |   28 |    202 |  202 | 销售         |
    |    5 | owen  | male   |   18 |    203 |  203 | 运营         |
    |    6 | jerry | female |   18 |    204 | NULL | NULL         |
    | NULL | NULL  | NULL   | NULL |   NULL |  205 | 美工         |
    +------+-------+--------+------+--------+------+--------------+
    7 rows in set (0.00 sec)
    
    mysql>

    三、符合条件连接查询

    #示例1:以内连接的方式查询emp和dep表,并且emp表中的age字段值必须大于25,即找出年龄大于25岁的员工以及员工所在的部门
    mysql> select emp.name as "员工姓名",dep.name as "部门名称" from emp inner join dep     on emp.dep_id = dep.id     where age > 25;
    +--------------+--------------+
    | 员工姓名     | 部门名称     |
    +--------------+--------------+
    | egon         | 人力资源     |
    | nick         | 销售         |
    +--------------+--------------+
    2 rows in set (0.00 sec)
    
    mysql>
    
    #示例2:以内连接的方式查询employee和department表,并且以age字段的升序方式显示
    mysql> select emp.id,emp.name,emp.age,dep.name from emp,dep
        ->     where emp.dep_id = dep.id
        ->     and age > 25
        ->     order by age asc;
    +----+------+------+--------------+
    | id | name | age  | name         |
    +----+------+------+--------------+
    |  4 | nick |   28 | 销售         |
    |  2 | egon |   48 | 人力资源     |
    +----+------+------+--------------+
    2 rows in set (0.00 sec)
    
    mysql> 

    四、子查询

    #1:子查询是将一个查询语句嵌套在另一个查询语句中。
    #2:内层查询语句的查询结果,可以为外层查询语句提供查询条件。
    #3:子查询中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等关键字
    #4:还可以包含比较运算符:= 、 !=、> 、<等

    1 带IN关键字的子查询

    """
    子查询就是我们平时解决问题的思路
        分步骤解决问题
            第一步
            第二步
            ...
    将一个查询语句的结果当做另外一个查询语句的条件去用
    """
    # 查询部门是技术或者人力资源的员工信息
        1 先获取部门的id号
        2 再去员工表里面筛选出对应的员工
        select id from dep where name='技术' or name = '人力资源';
        
        select name from emp where dep_id in (200,201);
        
        #上面两步等同于子查询:
        select * from emp where dep_id in (select id from dep where name='技术' or name = '人力资源');
    
    mysql> select * from emp where dep_id in (select id from dep where name='技术' or name = '人力资源');
    +----+-------+--------+------+--------+
    | id | name  | sex    | age  | dep_id |
    +----+-------+--------+------+--------+
    |  1 | jason | male   |   18 |    200 |
    |  2 | egon  | female |   48 |    201 |
    |  3 | kevin | male   |   18 |    201 |
    +----+-------+--------+------+--------+
    3 rows in set (0.00 sec)
    
    mysql>

    总结:

    表的查询结果可以作为其他表的查询条件
    也可以通过起别名的方式把它作为一个张虚拟表根其他表关联
    
    """
    多表查询就两种方式
        先拼接表再查询
        子查询 一步一步来
    """

    带比较的:

    mysql> select name from dep where id in
        -> (select dep_id from emp group by dep_id having avg(age) > 25);
    +--------------+
    | name         |
    +--------------+
    | 人力资源     |
    | 销售         |
    +--------------+
    2 rows in set (0.00 sec)
    
    mysql> 

    2 带比较运算符的子查询

    #比较运算符:=、!=、>、>=、<、<=、<>
    #查询大于所有人平均年龄的员工名与年龄
    mysql> select name,age from emp where age > (select avg(age) from emp);
    +------+------+
    | name | age  |
    +------+------+
    | egon |   48 |
    | nick |   28 |
    +------+------+
    2 rows in set (0.00 sec)
    
    mysql> 
    
    #查询大于部门内平均年龄的员工名、年龄 
    mysql> select t1.name,t1.age from emp t1
        -> inner join 
        -> (select dep_id,avg(age) avg_age from emp group by dep_id) t2
        -> on t1.dep_id = t2.dep_id
        -> where t1.age > t2.avg_age;
    +------+------+
    | name | age  |
    +------+------+
    | egon |   48 |
    +------+------+
    1 row in set (0.00 sec)
    
    mysql>

    3 带EXISTS关键字的子查询

    EXISTS关字键字表示存在。在使用EXISTS关键字时,内层查询语句不返回查询的记录。
    而是返回一个真假值。True或False
    当返回True时,外层查询语句将进行查询;当返回值为False时,外层查询语句不进行查询

    #dep表中存在dept_id=203,Ture
    mysql>  select * from emp 
        -> where exists
        ->  (select id from dep where id=200);
    +----+-------+--------+------+--------+
    | id | name  | sex    | age  | dep_id |
    +----+-------+--------+------+--------+
    |  1 | jason | male   |   18 |    200 |
    |  2 | egon  | female |   48 |    201 |
    |  3 | kevin | male   |   18 |    201 |
    |  4 | nick  | male   |   28 |    202 |
    |  5 | owen  | male   |   18 |    203 |
    |  6 | jerry | female |   18 |    204 |
    +----+-------+--------+------+--------+
    6 rows in set (0.00 sec)
    
    mysql> 
    
    #dep表中存在dept_id=205,False
    mysql> select * from emp
        -> where exists
        ->  (select id from dep where id=204);
    Empty set (0.00 sec)
    
    mysql> 
  • 相关阅读:
    光电缆线路安防综合监控网管运维方案
    5G时代 微波通信网络运维管理系统实施方案
    IT运维管理之NETCONF工具
    新基建 破局大规模数据中心智能化监控运维管理
    智慧工厂工业交换机网络运维管理系统
    智慧轨道交通云联网安防运维集成化管理系统应用方案
    智和网管平台SugarNMS万能命令工具 赋能IT智能运维
    智慧城市综合运维安防监控管理系统方案
    SugarNMS可视化智能运维 赋能数据中心安全管控
    下载时,经常看见ASC、MD5、SHA1等,是干什么的呢?
  • 原文地址:https://www.cnblogs.com/baicai37/p/12837838.html
Copyright © 2011-2022 走看看