//最近研究联合多表查询的问题,在网上看到一文章感觉不错特转过来

1.相关概念:


笛卡儿积

在数学中,两个集合XY笛卡儿积金沙城中心赌场 ,(Cartesian product),又称直积,表示为X ×
Y,是其第一个对象是X的成员而第二个对象是Y的一个成员的所有可能的有序对:

金沙城中心赌场 1

笛卡儿积得名于笛卡儿,他的解析几何的公式化引发了这个概念。

具体的说,如果集合X是13个元素的点数集合{ A,
K, Q, J, 10, 9, 8, 7, 6, 5, 4, 3, 2
}而集合Y是4个元素的花色集合{♠, ♥, ♦,
♣},则这两个集合的笛卡儿积是52个元素的标准扑克牌的集合{ (A, ♠), (K,
♠), …, (2, ♠), (A, ♥), …, (3, ♣), (2, ♣) }。

 

笛卡尔积形成的条件:

      1.查询语句中漏掉了连接条件

      2.查询语句中两个表中的所有行都满足连接条件

      3.查询语句中的连接条件无效

在实际工作中应该尽量的避免出现笛卡尔积,在多表连接查询语句的WHERE字句中,必须永远是用有效而正确的连接条件。

举例说明:select * from a,b,c where a.i
= c.i and c.i = b.i
假设,我规定表JOIN的顺序是从左到右
a到b,b到c
那上面这个语句,虽然有两个关联条件,也会发生笛卡尔积
因为a和b没有字段直接关联,a和b两个表就要先笛卡尔积了。

正确写法:select * from a,b,c where a.i = b.i and b.i = c.i

那select * from a,b,c where a.i = b.i and a.i = c.i会不会发生笛卡尔积呢?

不会,因为a,b已经正常的join出结果,已经过滤了很多数据,然后再去跟c关联。(a,b)和(c)这两个结果集是有关联条件的,就是a.i = c.i

只有没有关联条件的,才会发生笛卡尔积!

 

首先划分一下,连接分为三种:内连接、外连接、交叉连接 
 
内连接(INNER JOIN): 
    分为三种:等值连接、自然连接、不等连接 
     
外连接(OUTER JOIN): 
    分为三种: 
    左外连接(LEFT OUTER JOIN或LEFT JOIN) 
    右外连接(RIGHT OUTER JOIN或RIGHT JOIN) 
    全外连接(FULL OUTER JOIN或FULL JOIN) 
 
交叉连接(CROSS JOIN): 
    没有WHERE 子句,它返回连接表中所有数据行的笛卡尔积 

 

关键字:

1.

a. 并集UNION :SELECT column1, column2 FROM table1 UNION SELECT column1,
column2 FROM table2

b. 交集JOIN :SELECT * FROM table1 AS a JOIN table2 b ON a.name=b.name

c. 差集NOT IN :SELECT * FROM table1 WHERE name NOT IN(SELECT name FROM
table2)

d. 笛卡尔积CROSS JOIN :SELECT * FROM table1 CROSS JOIN table2 (   与
SELECT * FROM table1,table2相同)

 2.

SQL中的UNION 与UNION ALL的区别是,前者会去除重复的条目,后者会仍旧保留。

a. UNION :SQL Statement1 UNION SQL Statement2

b. UNION ALL: SQL Statement1 UNION ALL SQL Statement2

 

 

SQL中的各种JOIN,
SQL中的连接可以分为内连接,外连接,以及交叉连接(即是笛卡尔积)

a. 交叉连接 CROSS JOIN:

如果不带WHERE条件子句,它将会返回被连接的两个表的笛卡尔积,返回结果的行数等于两个表行数的乘积;
举例

SELECT * FROM table1 CROSS JOIN table2 等同于

SELECT * FROM table1,table2

一般不建议使用该方法,因为如果有WHERE子句的话,往往会先生成两个表行数乘积的行的数据表然后才根据WHERE条件从中选择。
因此,如果两个需要求交际的表太大,将会非常非常慢,不建议使用。

b. 内连接 INNER JOIN :

如果仅仅使用 SELECT * FROM table1 INNER JOIN table2
没有指定连接条件的话,和交叉连接的结果一样。 但是通常情况下,使用INNER
JOIN需要指定连接条件。

— 等值连接(=号应用于连接条件, 不会去除重复的列) SELECT * FROM table1
AS a INNER JOIN table2 AS b on a.column=b.column

— 不等连接(>,>=,<,<=,!>,!<,<>) 例如 SELECT *
FROM table1 AS a INNER JOIN table2 AS b on a.column<>b.column

— 自然连接(会去除重复的列)

c. 外连接 OUTER JOIN:

 首先内连接和外连接的不同之处:
内连接如果没有指定连接条件的话,和笛卡尔积的交叉连接结果一样,但是不同于笛卡尔积的地方是,没有笛卡尔积那么复杂地要先生成行数乘积的数据表,内连接的效率要高于笛卡尔积的交叉连接。
指定条件的内连接,仅仅返回符合连接条件的条目。外连接则不同,返回的结果不仅包含符合连接条件的行,而且包括左表(左外连接时),
右表(右连接时)或者两边连接(全外连接时)的所有数据行  

1)左外连接LEFT [OUTER] JOIN :


示符合条件的数据行,同时显示左边数据表不符合条件的数据行,右边没有对应的条目显示NULL
例如 SELECT * FROM table1 AS a LEFT [OUTER] JOIN table2 AS b ON
a.column=b.column                                                                                                                                     

2)右外连接RIGHT [OUTER] JOIN:

 显
示符合条件的数据行,同时显示右边数据表不符合条件的数据行,左边没有对应的条目显示NULL
例如 SELECT * FROM table1 AS a RIGHT [OUTER] JOIN table2 AS b ON
a.column=b.column                                                                                                                                               

3)全外连接:

显示符合条件的数据行,同时显示左右不符合条件的数据行,相应的左右两边显示NULL

 

内部连接 inner join 两表都满足的组合
full outer 全连
两表相同的组合在一起,A表有,B表没有的数据(显示为null),同样B表有
A表没有的显示为(null)
A表 left join B表
左连,以A表为基础,A表的全部数据,B表有的组合。没有的为null
A表 right join B表
右连,以B表为基础,B表的全部数据,A表的有的组合。没有的为null

查询分析器中执行:
–建表table1,table2:
create table table1(id int,name varchar(10))
create table table2(id int,score int)
insert into table1 select 1,’lee’
insert into table1 select 2,’zhang’
insert into table1 select 4,’wang’
insert into table2 select 1,90
insert into table2 select 2,100
insert into table2 select 3,70

如表

table1|table2|

idname|idscore|
1lee|190|
2zhang|2100|

4wang|370|

以下均在查询分析器中执行

一、外连接
1.概念:包括左向外联接、右向外联接或完整外部联接

2.左连接:left join 或 left outer join
(1)左向外联接的结果集包括 LEFT OUTER
子句中指定的左表的所有行,而不仅仅是联接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值(null)。
(2)sql语句
select * from table1 left join table2 on table1.id=table2.id
————-结果————-

idnameidscore

1lee190
2zhang2100

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图