zoukankan      html  css  js  c++  java
  • SQL基础-连接表

    一、连接表

    1、SQL JOIN

    忘记在哪保存的某位网友的图,先明白SQL JOIN,

    image


    2、关于笛卡尔积

    笛卡尔积:
        两个集合的乘积
    
    
    重新建student表和teacher表:
    
    student表:
    CREATE TABLE `student` (
      `student_id` varchar(50) NOT NULL COMMENT '学生编号',
      `student_name` varchar(100) NOT NULL DEFAULT '' COMMENT '学生姓名',
      `teacher_id` varchar(20) DEFAULT NULL COMMENT '老师编号'
    ) ENGINE=MyISAM DEFAULT CHARSET=gbk COMMENT='学生';
    
    INSERT INTO `student` VALUES ('S20180001','方东美','T0003'),('S20180013','陈顺军','T0004'),('S20170001','陈慧','T0008');
    
    
    teacher表:
    CREATE TABLE `teacher` (
      `teacher_id` varchar(255) DEFAULT NULL COMMENT '老师编号',
      `teacher_name` varchar(255) DEFAULT NULL COMMENT '老师姓名'
    ) ENGINE=MyISAM DEFAULT CHARSET=gbk COMMENT='老师';
    
    INSERT INTO `teacher` VALUES ('T0001','高齐妍'),('T0002','李红'),('T0003','李一萱'),('T0004','刘金霞');

    image


    交叉连接CROSS JOIN,实现两个集合的笛卡尔积

    SELECT * FROM student CROSS JOIN teacher;


    3、内连接INNER JOIN

    比如:
        如何同时查询出学生编号、学生姓名对应的 老师编号、老师姓名?
    
        select * from student a INNER JOIN teacher b ON a.teacher_id = b.teacher_id;
    
    
    相反的,如何返回这两张表里,老师编号不相同的记录?
    
        select * from student s inner join teacher t on s.teacher_id <> t.teacher_id;


    4、全外连接FULL OUTER JOIN

    比如:
        如何同时查询出学生编号、学生姓名、老师编号、老师姓名?
    
        select * from student a FULL OUTER JOIN teacher b ON a.teacher_id = b.teacher_id;
    
    
    MySQL不支持FULL OUTER JOIN


    5、左外连接FULL OUTER JOIN

    有时候只想要左表字段不为NULL的数据,而不需左表字段为NULL的数据;
    
    比如:
        如何同时查询出学生编号、学生姓名、老师编号、老师姓名?
    
        select * from student a LEFT OUTER JOIN teacher b ON a.teacher_id = b.teacher_id;


    6、右外连接FULL OUTER JOIN

    有时候只想要右表字段不为NULL的数据,而不需右表字段为NULL的数据;
    
    比如:
        如何同时查询出学生编号、学生姓名、老师编号、老师姓名?
    
        select * from student a RIGHT OUTER JOIN teacher b ON a.teacher_id = b.teacher_id;


    二、复杂的连接表

    1、建表、插入数据

    ##student表
    CREATE TABLE `student` (
      `student_id` varchar(50) NOT NULL COMMENT '学生编号',
      `student_name` varchar(100) NOT NULL DEFAULT '' COMMENT '学生姓名',
          `teacher_id` varchar(20) DEFAULT NULL COMMENT '老师编号',
      `score` decimal(18,2) NOT NULL DEFAULT '0.00' COMMENT '数学成绩'
    ) ENGINE=MyISAM DEFAULT CHARSET=gbk COMMENT='学生';
    
    
    INSERT INTO `student` VALUES ('S20180001','方东美','T0003',80.65),('S20180013','陈顺军','T0004',91.13),('S20170001','陈慧','T0004',94.99);
    
    
    
    ##teacher表
    CREATE TABLE `teacher` (
      `teacher_id` varchar(255) DEFAULT NULL COMMENT '老师编号',
      `teacher_name` varchar(255) DEFAULT NULL COMMENT '老师姓名'
    ) ENGINE=MyISAM DEFAULT CHARSET=gbk COMMENT='老师';
    
    INSERT INTO `teacher` VALUES ('T0001','高齐妍'),('T0002','李红'),('T0003','李一萱'),('T0004','刘金霞');


    2、连接表的执行步骤

    第一步:参与连接的两个表做笛卡尔积;
    
    第二步:根据ON后的连接条件筛选笛卡尔积的结果;
    
    第三步:补充左表(LEFT JOIN)或右表(RIGHT JOIN)不满足连接条件的数据(INNER JOIN内关联时无此步骤) ;
    
    第四步:根据WHERE后的过滤条件筛选第三步的结果;
    
    
    SELECT *  
    FROM student a 
    LEFT JOIN teacher b 
    ON a.teacher_id = b.teacher_id 
    WHERE a.score > 90;

    第一步:参与连接的两个表做笛卡尔积:

    image

    第二步:根据ON后的连接条件筛选笛卡尔积的结果:

    image

    第三步:补充左表(LEFT JOIN)或右表(RIGHT JOIN)不满足连接条件的数据(INNER JOIN内关联时无此步骤)

    image

    第四步:根据WHERE后的过滤条件筛选第三步的结果

    image


    3、LEFT JOIN与INNER JOIN

    image


    4、WHERE与ON

    ###
    看两个SQL:
        SELECT * 
        FROM student a 
        INNER JOIN teacher b 
        ON a.teacher_id = b.teacher_id
        AND a.score>90;
    
        SELECT * 
        FROM student a 
        INNER JOIN teacher b 
        ON a.teacher_id = b.teacher_id
        WHERE a.score>90;
    
    根据步骤,inner join时不走第三步,所以只返回一条记录:
        S20180013    陈顺军    T0004    91.13    T0004    刘金霞
    
    
    ###
    看两个SQL:
        SELECT * 
        FROM student a 
        LEFT JOIN teacher b 
        ON a.teacher_id = b.teacher_id
        AND a.score>90;
    
        SELECT * 
        FROM student a 
        LEFT JOIN teacher b 
        ON a.teacher_id = b.teacher_id
        WHERE a.score>90;
    
    根据步骤,第一条SQL left join时,要走第三步,AND是属于ON后面的,所以过滤后,又要补全left join不满住连接条件的数据:
    第一条SQL的结果:
        S20180013    陈顺军    T0004    91.13    T0004    刘金霞
        S20180001    方东美    T0003    80.65        
        S20170001    陈慧    T0008    94.99        
    
    第二条SQL,执行完第三步,还要走第四步where
    第二条SQL的结果:
        S20180013    陈顺军    T0004    91.13    T0004    刘金霞        
        S20170001    陈慧    T0008    94.99


    5、多表连接

    ##
    第一步:a表与b表做LEFT JOIN;
    第二步:a表与b表LEFT JOIN的结果,再与c表做LEFT JOIN;
    ......
    
    多表连接,就是第一张表与后面的表依次连接,重复执行表连接的步骤;
    
    此时可以给student表加一个class_id列,数据如下:
    S20180001    方东美    T0003    80.65    G0101
    S20180013    陈顺军    T0004    91.13    G0102
    S20170001    陈慧    T0008    94.99    G0201
    
    
    如:
        同时查看学生编号、学生姓名、老师编号、老师姓名、班级编号、班级名称:
    
        SELECT a.student_id,a.student_name,
                  a.teacher_id,b.teacher_name,
                  a.class_id,c.class_name
        FROM student a 
        LEFT JOIN teacher b 
        ON a.teacher_id = b.teacher_id
        LEFT JOIN class c
        ON a.class_id = c.class_id;


    6、非唯一键连接

    表关联时,首先需要确认的一点,就是关联条件字段在关联表中是不是唯一。
    
    在绝大多数的情况下,关联条件字段都是关联表中的主键或能唯一确定一条记录的字段。
    
    如果不是,很可能是SQL的关联条件有问题,需要仔细确认是否与需求相符。
  • 相关阅读:
    【★】IT界8大恐怖预言
    ★互联网告别免费时代,准备好了吗?
    ★互联网告别免费时代,准备好了吗?
    PS小实验-去除水印
    PS小实验-去除水印
    玩转PS路径,轻松画logo!
    玩转PS路径,轻松画logo!
    玩转PS路径,轻松画logo!
    地图收敛心得170405
    地图收敛心得170405
  • 原文地址:https://www.cnblogs.com/weiyiming007/p/11436002.html
Copyright © 2011-2022 走看看