mysql---笛卡尔积的理解--内连接--外连接

本文介绍了笛卡尔积的概念,从数学角度解释并举例说明。接着讨论了在MySQL中如何产生和避免笛卡尔积,并详细讲解了内连接和外连接(左连接、右连接、全外连接)的使用方法,结合实例阐述它们在数据查询中的作用和区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

笛卡尔积在MySQL上的一种运用;

数学上的学的笛卡尔积:

两个集合XY的笛卡尔积(Cartesian product),又称直积,表示为X×Y,第一个对象是X的成员而第二个对象是Y的所有可能有序对的其中一个成员

假设集合A={a, b},集合B={0, 1, 2},则两个集合的笛卡尔积为{(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}。

类似的例子有,如果A表示某学校学生的集合,B表示该学校所有课程的集合,则A与B的笛卡尔积表示所有可能的选课情况。A表示所有声母的集合,B表示所有韵母的集合,那么A和B的笛卡尔积就为所有可能的汉字全拼。

设A,B为集合,用A中元素为第一元素,B中元素为第二元素构成有序对,所有这样的有序对组成的集合叫做A与B的笛卡尔积,记作AxB.

笛卡尔积的符号化为:

A×B={(x,y)|x∈A∧y∈B}

例如,A={a,b}, B={0,1,2},则

A×B={(a, 0), (a, 1), (a, 2), (b, 0), (b, 1), (b, 2)}

B×A={(0, a), (0, b), (1, a), (1, b), (2, a), (2, b)}

MySQL上的笛卡尔积的使用

在查询语句中对多张表进行查询时就会用到笛卡尔积,比如有的时候会出现无效的笛卡尔积的时候,这个时候需要我们想办法将那些数据给消除了再进行查询

 select * from employee, dept;----这个语句会展示所有的笛卡尔积,会包括一些无效的笛卡尔积。

 select * from employee, dept where employee.dept = dept.id;通过where的条件查询的方式来进行查询,通过两张表的一个关联的关系来进行 匹配从而得到想要的结果----也就是消除笛卡尔积的结果。

内连接查询

在“设置表间关联关系”的界面中选择“=”,即为内连接。

两个表(或连接)中某一数据项相等的连接称为内连接。连接的结果是形成一个新的数据表。

内连接中参与连接的表(或连接)的地位是相等的。内连接的运算顺序是:

1.参与的数据表(或连接)中的每列与其它数据表(或连接)的列相匹配,形成临时数据表;

2.将满足数据项相等的记录从临时数据表中选择出来。

软道语录

内连接

内连接就是两张表都只显示符合连接条件的行。

例如:

假设有两个Excel报表:出货表和产品表

出货表:

日期 客户 产品编码 数量

2003-10-20 永华公司 1001 10

2003-10-21 风貌公司 1002 20

产品表:

产品编码 产品名称 生产厂家

1001 PC机 创成公司

1002 打印机 风华公司

内连接条件为:出货表.产品编码=产品表.产品编码

内连接的结果集为:

日期 客户 产品编号 数量 产品名称 生产厂家

2003-10-20 永华公司 1001 10 PC机 创成公司

2003-10-21 风貌公司 1002 20 打印机 风华公司

语法:

SELECT 字段列表 FROM 表1, 表2 WHERE 条件 ...;

SELECT 字段列表 FROM 表1 [ INNER ] JOIN 表2 ON 连接条件 ...;

例句:

-- 查询员工姓名,及关联的部门的名称

-- 隐式

select e.name, d.name from employee as e, dept as d where e.dept = d.id;

-- 显式

select e.name, d.name from employee as e inner join dept as d on e.dept = d.id;

外连接

外连接分为三种:左外连接,右外连接,全外连接。对应SQL:LEFT/RIGHT/FULL OUTER JOIN。

outer join则会返回每个满足第一个(顶端)输入与第二个(底端)输入的联接的行。它还返回任何在第二个输入中没有匹配行的第一个输入中的行。

通常我们省略outer 这个关键字。写成:LEFT/RIGHT/FULL JOIN。

全外连接(fullouter join/ full join)

左表和右表都不做限制,所有的记录都显示,两表不足的地方用null 填充。 全外连接不支持(+)这种写法。

示例:

SQL> select * from dave a full join bl b on a .id = b .id;

ID NAME ID NAME

---------- ---------- ---------- ----------

8 安庆

1 dave 1 dave

2 bl 2 bl

1 bl 1 dave

2 dave 2 bl

3 dba 3 big bird

4 sf-express 4 exc

5 dmm

9 怀宁

已选择9行。

SQL> select * from dave a full outer join bl b on a .id = b .id;

ID NAME ID NAME

---------- ---------- ---------- ----------

8 安庆

1 dave 1 dave

2 bl 2 bl

1 bl 1 dave

2 dave 2 bl

3 dba 3 big bird

4 sf-express 4 exc

5 dmm

9 怀宁

已选择9行。

左外连接(Left outer join/ left join)

left join是以左表的记录为基础的,示例中Dave可以看成左表,BL可以看成右表,它的结果集是Dave表中的数据,在加上Dave表和BL表匹配的数据。换句话说,左表(Dave)的记录将会全部表示出来,而右表(BL)只会显示符合搜索条件的记录。BL表记录不足的地方均为NULL。

示例:

SQL> select *from dave a left join bl b on a .id=b .id ;

ID NAME ID NAME

--------- ---------- ---------- ----------

1 bl 1 dave

1 dave 1 dave

2 dave 2 bl

2 bl 2 bl

3 dba 3 big bird

4 sf-express 4 exc

5 dmm -- 此处B表为null,因为没有匹配到

8 安庆 -- 此处B表为null,因为没有匹配到

SQL> select *from dave a left outer join bl b on a .id= b .id;

ID NAME ID NAME

---------- ---------- ---------- ----------

1 bl 1 dave

1 dave 1 dave

2 dave 2 bl

2 bl 2 bl

3 dba 3 big bird

4 sf-express 4 exc

5 dmm

8 安庆

用(+)来实现, 这个加号可以这样来理解:+ 表示补充,即哪个表有加号,这个表就是匹配表。所以加号写在右表,左表就是全部显示,故是左连接。

SQL> Select *from dave a,bl b where a .id=b .id(+); -- 注意: 用(+) 就要用关键字where

ID NAME ID NAME

---------- ---------- ---------- ----------

1 bl 1 dave

1 dave 1 dave

2 dave 2 bl

2 bl 2 bl

3 dba 3 big bird

4 sf-express 4 exc

5 dmm

8 安庆

右外连接(rightouter join/ right join)

和left join的结果刚好相反,是以右表(BL)为基础的, 显示BL表的所以记录,在加上Dave和BL 匹配的结果。Dave表不足的地方用NULL填充。

示例:

SQL>select * from dave a right join bl b on a .id = b .id;

ID NAME ID NAME

---------- ---------- ---------- ----------

1 dave 1 dave

2 bl 2 bl

1 bl 1 dave

2 dave 2 bl

3 dba 3 big bird

4 sf-express 4 exc

9 怀宁 --此处左表不足用Null填充

已选择7行。

SQL>select * from dave a right outer join bl b on a .id= b .id;

ID NAME ID NAME

---------- ---------- ---------- ----------

1 dave 1 dave

2 bl 2 bl

1 bl 1 dave

2 dave 2 bl

3 dba 3 big bird

4 sf-express 4 exc

9 怀宁 --此处左表不足用Null填充

已选择7行。

用(+)来实现, 这个+号可以这样来理解:+ 表示补充,即哪个表有加号,这个表就是匹配表。所以加号写在左表,右表就是全部显示,故是右连接。

SQL> Select * from dave a,bl b where a .id(+)=b .id;

ID NAME ID NAME

---------- ---------- ---------- ----------

1 dave 1 dave

2 bl 2 bl

1 bl 1 dave

2 dave 2 bl

3 dba 3 big bird

4 sf-express 4 exc

9 怀宁

语法:

左外连接:
查询左表所有数据,以及两张表交集部分数据
SELECT 字段列表 FROM 表1 LEFT [ OUTER ] JOIN 表2 ON 条件 ...;
相当于查询表1的所有数据,包含表1和表2交集部分数据
右外连接:
查询右表所有数据,以及两张表交集部分数据
SELECT 字段列表 FROM 表1 RIGHT [ OUTER ] JOIN 表2 ON 条件 ...;

例句:

-- 左
select e.*, d.name from employee as e left outer join dept as d on e.dept =
d.id;
select d.name, e.* from dept d left outer join emp e on e.dept = d.id; -- 这条语
句与下面的语句效果一样
-- 右
select d.name, e.* from employee as e right outer join dept as d on e.dept =
d.id

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值