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> 
  • 相关阅读:
    Linnia学习记录
    漫漫考研路
    ENS的学习记录
    KnockoutJS 3.X API 第四章 数据绑定(4) 控制流with绑定
    KnockoutJS 3.X API 第四章 数据绑定(3) 控制流if绑定和ifnot绑定
    KnockoutJS 3.X API 第四章 数据绑定(2) 控制流foreach绑定
    KnockoutJS 3.X API 第四章 数据绑定(1) 文本及样式绑定
    KnockoutJS 3.X API 第三章 计算监控属性(5) 参考手册
    KnockoutJS 3.X API 第三章 计算监控属性(4)Pure computed observables
    KnockoutJS 3.X API 第三章 计算监控属性(3) KO如何实现依赖追踪
  • 原文地址:https://www.cnblogs.com/baicai37/p/12837838.html
Copyright © 2011-2022 走看看