笛卡尔积在MySQL上的一种运用;
数学上的学的笛卡尔积:
两个集合X和Y的笛卡尔积(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