zoukankan      html  css  js  c++  java
  • MySQL 之 多表连接查询及子查询

    1、前期准备

    #建表
    create table department(
    id int,
    name varchar(20) 
    );
    
    create table employee(
    id int,
    name varchar(20),
    sex enum('male','female'),
    age int,
    dep_id int
    );
    
    #插入数据
    insert into department values
    (200,'技术'),
    (201,'人力资源'),
    (202,'销售'),
    (203,'运营');
    
    insert into employee(id,name,sex,age,dep_id) values
    (1,'cai','male',18,200),
    (2,'liu','female',48,201),
    (3,'ling','male',38,201),
    (4,'liangliang','female',28,202),
    (5,'acai','male',18,200),
    (6,'bao','female',18,204)
    ;
    

    2、连表

    (1)、 交叉连接:不使用任何匹配条件。生成笛卡尔积

    select * from employee,department;
    

    (2)、 内连接:只连接匹配的行(所有不在条件匹配内的数据,都会被剔出连表)

    # 方式一 :
    	select * from employee,department where dep_id = department.id;
    # 方式二 :
    	select * from employee inner join department on dep_id = department.id;
    

    (3)、 外连接

    左外连接:优先显示左表全部记录(本质就是在内连接的基础上增加左边有右边没有的结果)

    右外连接:优先显示右表全部记录(本质就是在内连接的基础上增加右边有左边没有的结果)

    全外连接:显示左右两个表全部记录(mysql 不支持全外连接,但可以间接实现全外连接)

    # 左外连接 left join
    	select * from employee left join department on dep_id = department.id;
    # 右外连接 right join
    	select * from employee right join department on dep_id = department.id;
    # 全外连接 full join (mysql中不支持)
    	# 在mysql中实现全外连接的方法
    	select * from employee left join department on dep_id = department.id
    	union
    	select * from employee right join department on dep_id = department.id;
    

    3、符合条件查询连接

    # 示例1:以内连接的方式查询employee和department表,并且employee表中的age字段值必须大于25,即找出年龄大于25岁的员工以及员工所在的部门
        select employee.name,department.name from employee inner join department on dep_id = department.id where age>25;
        select e.name ename,d.name dname from employee e inner join department d on dep_id = d.id where age>25;
        select e.name,d.name from employee e inner join department d on dep_id = d.id where age>25;
    
    # 示例2:以内连接的方式查询employee和department表,并且以age字段的升序方式显示。
        select * from employee inner join department on dep_id = department.id order by age;
    

    4、子查询

    (1)、 带 in 关键字的子查询

    # 查询平均年龄在25岁以上的部门名
        select name from department where id in (select dep_id from employee group by dep_id having avg(age)>25);
        
    # 查看不足1人的部门名(子查询得到的是有人的部门id)
         # 分步完成
        	先从employee中查有多少个部门有人
                select distinct dep_id from employee;
            从department表中把不在上述部门中的那些项找出来
                select * from department where id not in (200,201,202,204);
         # 组合结果
                select * from department where id not in (select distinct dep_id from employee);
    

    (2)、 带比较运算符的子查询

    比较运算符: = != > < >= <= <>

    # 查看技术部员工姓名
        # 分步完成 
        	先查询技术部的id
              	select id from department where name = '技术';
         	根据技术部id查询employee表 找到技术部id对应的人名
                select * from employee where dep_id = 200;
         # 组合结果
                select name from employee where dep_id = (select id from department where name = '技术');
    
    # 查询大于所有人平均年龄的员工名与年龄
        # 分步完成   
            所有人的平均年龄
                select avg(age) from employee;   # 28
            查大于上述平均年龄的人
                select name,age from employee where age>28;
        # 组合结果
                select name,age from employee where age>(select avg(age) from employee);
            
    # 查询大于部门内平均年龄的员工名、年龄
        # 分步完成    
            查询各部门平均年龄
                select dep_id,avg(age) from employee group by dep_id;
            查大于部门平均年龄的人
                select * from employee where dep_id = 200 and age>18
                select * from employee where dep_id = 201 and age>43
                select * from employee where dep_id = 202 and age>28
                select * from employee where dep_id = 204 and age>18
        # 组合结果
                select * from employee inner join (select dep_id,avg(age) as avg_age from employee group by dep_id) as t on employee.dep_id = t.dep_id;
    
                select * from employee inner join (select dep_id,avg(age) as avg_age  from employee group by dep_id) as t on employee.dep_id = t.dep_id where age>avg_age;
    

    (3)、 带 exists 关键字的查询

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

    # 内层查询返回True,外层查询会进行
    select name from employee1 where exists(select * from department where id=200);
    # 内层查询返回False,外层查询不会进行
    select name from employee1 where exists(select * from department where id=205);
    
  • 相关阅读:
    面向接口程序设计思想实践
    Block Chain Learning Notes
    ECMAScript 6.0
    Etcd Learning Notes
    Travis CI Build Continuous Integration
    Markdown Learning Notes
    SPRING MICROSERVICES IN ACTION
    Java Interview Questions Summary
    Node.js Learning Notes
    Apache Thrift Learning Notes
  • 原文地址:https://www.cnblogs.com/caiyongliang/p/13865325.html
Copyright © 2011-2022 走看看