MySQL—关联(连接)查询(笛卡尔积、内连接、外连接、左连接、右外连接、外连接、自连接)

Wesley13
• 阅读 1036

MySQL—关联(连接)查询

知识大纲

  • 概述
  • 笛卡尔积
  • 关联条件
  • 内连接 [INNER JOIN]
  • 外连接 [OUTER JOIN]
  • 左连接 [LEFT JOIN] 右外
  • 连接 [RIGHT JOIN]
  • 外连接 [FULL JOIN]
  • 自连接

1.概述

MySQL—关联(连接)查询(笛卡尔积、内连接、外连接、左连接、右外连接、外连接、自连接)
MySQL—关联(连接)查询(笛卡尔积、内连接、外连接、左连接、右外连接、外连接、自连接)

关联查询一共有几种情况:

  • 内连接:INNER JOIN 、CROSS JOIN
  • 外连接:左外连接(LEFT OUTER JOIN)、右外连接(RIGHT OUTER JOIN)、全 外连接(FULL OUTER JOIN)
  • 自连接:当 table1 和 table2 本质上是同一张表,只是用取别名的方式虚拟成两 张表以代表不同的意义

说明:

  • 连接 n 个表,至少需要 n-1 个连接条件。 例如:连接三个表,至少需要两个连接条件。
  • 当两个关联查询的表如果有字段名字相同,并且要查询中涉及该关联字段,那 么需要使用表名前缀加以区分
  • 当如果表名比较长时,可以给表取别名,简化 SQL 语句

MySQL—关联(连接)查询(笛卡尔积、内连接、外连接、左连接、右外连接、外连接、自连接)
MySQL—关联(连接)查询(笛卡尔积、内连接、外连接、左连接、右外连接、外连接、自连接)

示例

#连接[关联]查询

DROP TABLE IF EXISTS souce;
DROP TABLE IF EXISTS student;

#学生表
CREATE TABLE student
(
        s_id VARCHAR(20),
        name VARCHAR(20),
        sex CHAR(2),
        age INT,
        PRIMARY KEY(s_id)
);
INSERT INTO student VALUES
    ('A1001','张三','男',15),
    ('A1002','李四','女',16),
    ('B1001','王五','男',17),
    ('C1001','赵六','女',18);

#成绩表
CREATE TABLE souce
(
        t_id VARCHAR(20),
        C FLOAT,
        MySQL FLOAT,
        Java FLOAT,
        s_id VARCHAR(20),
        PRIMARY KEY(t_id),
        FOREIGN KEY(s_id) REFERENCES student(s_id) ON UPDATE CASCADE
);
INSERT INTO souce VALUES
    ('T001',66,77,88,'A1001'),
    ('T002',65,75,85,'A1002'),
    ('T003',84,85,86,'B1001');

SELECT * FROM student;
SELECT * FROM souce;

#查询每一个参加了考试的同学 的三科测试成绩[学生学号、学生姓名、C、MySQL、Java]
SELECT student.s_id,name,C,MySQL,Java FROM student,souce 
    WHERE student.s_id=souce.s_id;
#使用别名 简化查询语句中表名的录入
SELECT st.s_id,name,C,MySQL,Java FROM student st,souce s 
    WHERE st.s_id=s.s_id;

#查询每一个所有同学 的三科测试成绩[学生学号、学生姓名、C、MySQL、Java]
SELECT st.s_id,name,C,MySQL,Java FROM student st LEFT JOIN souce s 
    ON st.s_id=s.s_id;

2.笛卡尔积

定义:将两(或多)个表的所有行进行组合,连接后的行数为两(或多)个表的乘积数.

在 MySQL 中如下情况会出现笛卡尔积,主要是因为缺少关联条件或者关联条件不准确 注:外连接必须写关联条件,否则报语法错误

示例

#笛卡尔积 [原因:没有提供关联条件 或 关联条件失效]
SELECT name,Java FROM student,souce;
SELECT name,Java FROM student INNER JOIN souce;
SELECT name,Java FROM student JOIN souce;
SELECT name,Java FROM student CROSS JOIN souce;

3.关联条件

表连接的约束条件可以有三种方式:WHERE, ON, USING

  • WHERE:适用于所有关联查询
  • ON:只能和 JOIN 一起使用,只能写关联条件。虽然关联条件可以并到 WHERE 中和其他条件一起写,但分开写可读性更好
  • USING:只能和JOIN一起使用,而且要求两个关联字段在关联表中名称一致, 而且只能表示关联字段值相等

示例

#WHERE [关联条件 AND 查询条件]
SELECT student.s_id,name,C,MySQL,Java FROM student,souce 
    WHERE student.s_id=souce.s_id AND student.s_id='A1001';
#JOIN ON [关联条件]
SELECT st.s_id,name,C,MySQL,Java FROM student st LEFT JOIN souce s 
    ON st.s_id=s.s_id;
#USING [关联条件]
SELECT st.s_id,name,C,MySQL,Java FROM student st LEFT JOIN souce s 
    USING(s_id);

4.内连接

有两种格式,显式的和隐式的,返回连接表中符合连接条件和查询条件的数据行

隐式:

SELECT [cols_list] from 表 1,表 2 where [condition]

显式:

SELECT [cols_list] from 表 1 INNER JOIN 表 2 ON [关联条件] where [其他筛选条件]
SELECT [cols_list] from 表 1 CROSS JOIN 表 2 ON [关联条件] where [其他筛选条件]
SELECT [cols_list] from 表 1 JOIN 表 2 ON [关联条件] where [其他筛选条件]

MySQL—关联(连接)查询(笛卡尔积、内连接、外连接、左连接、右外连接、外连接、自连接)

示例

#查询员工姓名,基本工资,部门名称
#隐式内连查询
SELECT ename,basic_salary,dname FROM t_employee e,t_department d,t_salary s
    WHERE e.dept_id=d.did AND e.eid=s.eid;

SELECT ename,basic_salary,dname FROM t_employee e,t_department d,t_salary s
    WHERE e.dept_id=d.did AND e.eid=s.eid AND ename='孙红雷';

#隐式内连查询
SELECT ename,basic_salary,dname FROM t_employee e INNER JOIN t_department d
    INNER JOIN t_salary s
    ON e.dept_id=d.did AND e.eid=s.eid;

SELECT ename,basic_salary,dname FROM t_employee e JOIN t_department d
    INNER JOIN t_salary s
    ON e.dept_id=d.did AND e.eid=s.eid;

SELECT ename,basic_salary,dname FROM t_employee e 
    CROSS JOIN t_department d
    INNER JOIN t_salary s
    ON e.dept_id=d.did AND e.eid=s.eid
    WHERE ename='孙红雷';

5.外连接

外连接分为: 左外连接(LEFT OUTER JOIN),简称左连接(LEFT JOIN)

右外连接(RIGHT OUTER JOIN),简称右连接(RIGHT JOIN)

全外连接(FULL OUTER JOIN),简称全连接(FULL JOIN)。


6.左连接

MySQL—关联(连接)查询(笛卡尔积、内连接、外连接、左连接、右外连接、外连接、自连接)

7.右外连接

MySQL—关联(连接)查询(笛卡尔积、内连接、外连接、左连接、右外连接、外连接、自连接)

示例

#左连接
#查询所有部门信息以及该部门员工信息
SELECT did,dname,eid,ename FROM t_department d LEFT JOIN t_employee e
    ON d.did=e.dept_id;

SELECT did,dname,eid,ename FROM t_employee e LEFT JOIN t_department d
    ON d.did=e.dept_id;

SELECT did,dname,eid,ename FROM t_department d RIGHT JOIN t_employee e
    ON d.did=e.dept_id;

UPDATE t_employee SET dept_id=NULL where eid=5;

SELECT did,dname,eid,ename FROM t_department d LEFT JOIN t_employee e
    ON d.did=e.dept_id;
    WHERE e.dept_id IS NULL;
#查询部门信息,保留没有员工的部门信息
SELECT did,dname,eid,ename FROM t_department d RIGHT JOIN t_employee e
    ON d.did=e.dept_id;
    WHERE e.dept_id IS NULL;

SELECT did,dname,eid,ename FROM t_employee e LEFT JOIN t_department d
    ON d.did=e.dept_id;
    WHERE e.dept_id IS NULL;
    
#查询所有员工信息,以及员工的部门信息
SELECT eid,ename,did,dname FROM t_employee e LEFT JOIN t_department d 
    ON e.dept_id=d.did;

SELECT eid,ename,did,dname FROM t_department d LEFT JOIN t_employee e
    ON e.dept_id=d.did;

#查询员工信息,仅保留没有分配部门的员工
SELECT eid,ename,did,dname FROM t_employee e LEFT JOIN t_department d 
    ON e.dept_id=d.did
    WHERE e.dept_id IS NULL;
#查询员工信息,不保留没有分配部门的员工    
SELECT eid,ename,did,dname FROM t_employee e LEFT JOIN t_department d 
    ON e.dept_id=d.did
    WHERE e.dept_id IS NOT NULL;

SELECT id,ename,tid,dname FROM student_info s LEFT JOIN student_test t
    ON s.id_id=t.tid
    WHERE t.tid IS NOT NULL;

SELECT * FROM student;
SELECT * FROM souce;
#分析 左右外连接
#显示所有学生的测试信息
SELECT st.s_id,name,C,Java FROM student st LEFT JOIN souce s
    ON st.s_id=s.s_id;

#显示参加考试的学生的测试信息
SELECT st.s_id,name,C,Java FROM student st RIGHT JOIN souce s
    ON st.s_id=s.s_id;

8.外连接

mysql 不支持 FULL JOIN,但是可以用 left join union right join 代替

MySQL—关联(连接)查询(笛卡尔积、内连接、外连接、左连接、右外连接、外连接、自连接)

示例

#使用UNION 实现MySQL中不支持的FULL JOIN操作[完全外连接]
#查询所有部门信息和员工信息
SELECT did,dname,eid,ename FROM t_department d LEFT JOIN t_employee e
    ON d.did=e.dept_id
    UNION #联合查询 [整合多个查询]
SELECT did,dname,eid,ename FROM t_department d RIGHT JOIN t_employee e
    ON d.did=e.dept_id;

9.自连接

当 table1 和 table2 本质上是同一张表,只是用取别名的方式虚拟成两张表以代表不同 的意义。然后两个表再进行内连接,外连接等查询

#自连接
#查询员工姓名以及领导姓名,仅显示有领导的员工[自连接 内连]
SELECT e1.ename,e2.ename FROM t_employee e1, t_employee e2
    WHERE e1.mid=e2.eid;

SELECT e1.ename,e2.ename FROM t_employee e1 INNER JOIN t_employee e2
    ON e1.mid=e2.eid;

#查询所有员工姓名及其领导姓名[自连接 外连]
SELECT e1.ename,e2.ename FROM t_employee e1 LEFT JOIN t_employee e2
    ON e1.mid=e2.eid;
SELECT e1.ename,e2.ename FROM t_employee e1 RIGHT JOIN t_employee e2
    ON e1.mid=e2.eid;
    
#若涉及到多表连接查询 应使中间表连接居中
#book JOIN readbook ON xxx=xxx JOIN stuinfo ON xxx=xxx
#查询哪一本书[b_name] 在 什么时间[r_time] 被 何人所借[s_name]
SELECT b.b_name,r.r_time,s.s_name FROM book b JOIN readbook r ON b.b_id=r.b_id
    JOIN stuinfo s ON s.s_id=r.s_id;
点赞
收藏
评论区
推荐文章
Easter79 Easter79
3年前
sql语句中的 inner join 、 left join 、 right join、 full join 的区别
简单明了地说,连接分内连接和外链接假设有A和B两张表内连接:innerjoin   表示把AB表的记录相符都显示出来,把AB表不符合条件的都排除外连接分三种,即左连接(LEFTOUTERJOIN)、右连接(RIGHTOUTERJOIN)、全连接(FULLOUTERJOIN),下面就简单解析一下,。1.ALEFTOUTERJOI
kenx kenx
3年前
MySQL查询之内连接,外连接查询场景的区别与不同
前言我在写sql查询的时候,用的最多的就是where条件查询,这种查询也叫内连查询innerjoin,当然还有外连查询outerjoin,左外连接,右外连接查询,常用在多对多关系中,那他们区别和联系是什么呢?内连接innerjoin内连接最常用定义:1.连接结果仅包含符合连接条件的行组合起来作为结果集,参与连接的两个表都应该符合连接条件使用关键词:
Wesley13 Wesley13
3年前
MySQL数据库查询
MySQL数据库查询12、说明:使用外连接A、left(outer)join:左外连接(左连接):包含leftjoin左表所有行,如果左表中某行在右表没有匹配,则结果中对应行右表的部分全部为空(NULL).。SQL:select\fromstudent(表1)leftjoincourse(表2)onstude
Wesley13 Wesley13
3年前
MySQL教程(十四)—— 连接
1 连接的语法结构MySQL在SELECT语句、多表更新、多表删除语句中支持JOIN操作。语法结构:1table_reference//第一张表2{INNER|CROSSJOIN|{LEFT|RIGHT}OUTERJOIN}//连接选择:内连接,左外、右外连接3t
Wesley13 Wesley13
3年前
mysql学习之join从句
一、join从句共有5种类型内连接(innerjoin)全外连接(fullouterjoin)左外连接(leftouterjoin)右外连接(rightouterjoin)交叉连接(crossjoin)二、演示案例新建两张表user1表和user2表CRE
Wesley13 Wesley13
3年前
mysql2_4
连接查询将多张表进行记录的连接(按照某个指定的条件进行数据拼接)  最终结果是:记录数有可能变化,字段书一定会增加(至少两张表的合并)  连接查询的意义:在用户查看数据的时候,需要显示的数据来自多张表。  连接查询分类sql中将连接查询分成四类:内连接,外连接,自然连接,交叉连接  1.交叉连接:crossjoi
Wesley13 Wesley13
3年前
Oracle 中的join
1、概述1.1、所有的join连接,都可以加上类似wherea.id'1000'的条件,达到同样的效果。1.2、除了crossjoin不可以加on外,其它join连接都必须加上on关键字,后都可加where条件。1.3、虽然都可以加where条件,但是他们只在标准连接的结果集上查找where条件。比如左外连接的结果没有class的三
Wesley13 Wesley13
3年前
inner join(等值联接)、left join(左联接)、right join(右联接)用法及区别
innerjoin(等值连接)只返回两个表中联结字段相等的行leftjoin(左联接)返回包括左表中的所有记录和右表中联结字段相等的记录rightjoin(右联接)返回包括右表中的所有记录和左表中联结字段相等的记录INNERJOIN语法:INNERJOIN连接两个数据表的用法:SELECT\FROM
Wesley13 Wesley13
3年前
oracle外连接
外连接\外链接是标准连接的扩展,它不仅会返回满足连接条件的所有记录,而且还会返回不满足条件的部分记录。\举例:\按部门统计员工的人数,要求显示:部门号,部门名称,人数!(https://images2018.cnblogs.com/blog/1417765/201809/141776520180912225049373108
Wesley13 Wesley13
3年前
oracle连接种类
等连接:连接条件使用等号非等连接:连接条件使用等号以外的其它符号内连接:根据指定的连接条件进行连接查询,满足连接条件的数据才会出现在结果集外连接:在内连接的基础上,将某个连接表不符合连接条件的记录加入结果集自连接:自身表中的列关联自身表中的其它列内连接属于强连接,外连接属于弱连接左外连接【Aleftouterjoin