您的位置:首页 > 数据库

数据库表的连接(Left join , Right Join, Inner Join)用法详解

2011-03-07 15:39 218 查看
Left Join, Inner Join
的相关内容,非常实用,对于理解原理和具体应用都很有帮助!



left join 是left outer
join的简写,left join默认是outer属性的。


Inner Join

Inner Join
逻辑运算符返回满足第一个(顶端)输入与第二个(底端)输入联接的每一行。这个和用select查询多表是一样的效果,所以很少用到;

outer
join则会返回每个满足第一个(顶端)输入与第二个(底端)输入的联接的行。它还返回任何在第二个输入中没有匹配行的第一个输入中的行。关键就是后面那句,返回的多一些。所以通常意义上的left
join就是left outer join

一.先看一些最简单的例子


例子

Table A

aid adate

1 a1

2 a2

3 a3

TableB

bid bdate

1 b1

2 b2

4 b4

两个表a,b相连接,要取出id相同的字段

select * from a inner join

b on
a.aid = b.bid这是仅取出匹配的数据.

此时的取出的是:

1 a1 b1

2 a2 b2

那么left
join 指:

select * from a left
join

b on a.aid = b.bid

首先取出a表中所有数据,然后再加上与a,b匹配的的数据

此时的取出的是:

1 a1 b1

2 a2 b2

3 a3 空字符

同样的也有right join


指的是首先取出b表中所有数据,然后再加上与a,b匹配的的数据

此时的取出的是:

1 a1 b1

2 a2 b2

4 空字符 b4

LEFT JOIN 或 LEFT OUTER
JOIN。

左向外联接的结果集包括 LEFT OUTER
子句中指定的左表的所有行,而不仅仅是联接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值

二. left join/right join/inner
join操作演示


表A记录如下:

aID aNum

1
a20050111

2 a20050112

3 a20050113

4
a20050114

5 a20050115

表B记录如下:

bID bName

1
2006032401

2 2006032402

3 2006032403

4
2006032404

8 2006032408

实验如下:

1. left join

sql语句如下:

SELECT

*

FROM

A

LEFT

JOIN
B

ON
A.aID
=

B.bID


结果如下:

aID aNum bID
bName

1 a20050111 1
2006032401

2 a20050112 2
2006032402

3 a20050113 3
2006032403

4 a20050114 4
2006032404

5 a20050115 NULL NULL

(所影响的行数为
5 行)

结果说明:

left
join是以A表的记录为基础的,A可以看成左表,B可以看成右表,left
join是以左表为准的.

换句话说,左表(A)的记录将会全部表示出来,而右表(B)只会显示符合搜索条件的记录(例子中为: A.aID =
B.bID).

B表记录不足的地方均为NULL.

2. right join

sql语句如下:

SELECT

*

FROM

A

RIGHT

JOIN
B

ON
A.aID
=

B.bID


结果如下:

aID aNum bID
bName

1 a20050111 1
2006032401

2 a20050112 2
2006032402

3 a20050113 3
2006032403

4 a20050114 4
2006032404

NULL NULL 8
2006032408

(所影响的行数为 5 行)

结果说明:

仔细观察一下,就会发现,和left
join的结果刚好相反,这次是以右表(B)为基础的,A表不足的地方用NULL填充.

3.inner join

sql语句如下:

SELECT

*

FROM

A

INNERJOIN B

ON
A.aID
=

B.bID


结果如下:

aID aNum bID
bName

1 a20050111 1
2006032401

2 a20050112 2
2006032402

3 a20050113 3
2006032403

4 a20050114 4
2006032404

结果说明:

很明显,这里只显示出了
A.aID = B.bID的记录.这说明inner join并不以谁为基础,它只显示符合条件的记录.

-----------------[以下为网上的一点资料]------------------

LEFT JOIN操作用于在任何的 FROM
子句中,组合来源表的记录。使用 LEFT JOIN
运算来创建一个左边外部联接。左边外部联接将包含了从第一个(左边)开始的两个表中的全部记录,即使在第二个(右边)表中并没有相符值的记录。

语法:

FROM table1 LEFT JOIN table2 ON table1.field1
compopr table2.field2

说明:

① table1, table2参数用于指定要将记录组合的表的名称。

② field1,
field2参数指定被联接的字段的名称。且这些字段必须有相同的数据类型及包含相同类型的数据,但它们不需要有相同的名称。

③ compopr参数指定关系比较运算符:"=",
"<", ">", "<=", ">=" 或 "<>"。

④ 如果在INNER JOIN操作中要联接包含Memo
数据类型或 OLE Object 数据类型数据的字段,将会发生错误。

三.相关的复杂的解释和实例


简介: 外部连接和自联接 inner join(等值连接) 只返回两个表中联结字段相等的行 left join(左联接)
返回包括左表中的所有记录和右表中联结字段相等的记录 right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录 on
指定表间联结字段及其关系的等号 "=" 表达式, 返回 true 或 false. 当表达式返回 true 时, 则查询中包含该记录. !
外部连接只能操作已存在于数据库中的数据

update (ctarticle as a left join ctclass as c on
a.classid = c.classid) left join cttag as b on a.articleid = b.articleid

set
tag=tag+' ', b.articleid=a.articleid, b.classid=a.classid, b.nclassid=a.nclassid

where a.classid=23 and a.nclassid=0 and tagid is not null

update
(ctarticle as a left join (ctnclass as c left join ctclass as d on c.classid =
d.classid) on a.nclassid = c.nclassid and a.classid = c.classid) left join cttag
as b on a.articleid = b.articleid set tag=d.class+' '+c.nclass,
b.articleid=a.articleid, b.classid=a.classid, b.nclassid=a.nclassid where
a.classid=23 and a.nclassid=197;

更新操作

左连接中数据的筛选

insert into
cttag(articleid,classid,nclassid) select a.articleid,a.classid,a.nclassid from
ctarticle a left join cttag b on a.articleid=b.articleid where b.articleid is
null

//本语句功能为, 显示主表的全部内容, 插入数据到副表中没有的数据

//主要作用为: 让数据减少冗余

上例中的延续

select a.*, b.*, c.*, d.* from cttag as d left join
((ctarticle as a left join ctclass as b on a.classid=b.classid) left join
ctnclass as c on a.nclassid=c.nclassid) on d.articleid=a.articleid;

显示文章表中的全部, 调用类别表中的栏目

select a.*, b.*, c.* from (ctarticle a left
join ctclass b on a.classid=b.classid) left join ctnclass c on
a.nclassid=c.nclassid

//作用, 有时在文章表中包含了在个别类别表中没有的数据, 用这个语法可以读出文章表的全部数据

//a 为 文章表, b 为主类别, c 为子类别

同上例, 选择追加数据时加上空格

insert into
cttag(articleid,classid,nclassid,tag) select
a.articleid,a.classid,a.nclassid,d.class+' '+c.nclass

from (ctarticle as a
left join (ctnclass c left join ctclass d on c.classid=d.classid) on
a.classid=c.classid and a.nclassid=c.nclassid) left join cttag as b on
a.articleid = b.articleid where a.classid=4 and a.nclassid=154;

连接n个表,
并追加数据到其中一个表, n=4

insert into cttag(articleid,classid,nclassid,tag) select
a.articleid,a.classid,a.nclassid,d.class+c.nclass

from (ctarticle as a left
join (ctnclass c left join ctclass d on c.classid=d.classid) on
a.classid=c.classid and a.nclassid=c.nclassid) left join cttag as b on
a.articleid = b.articleid where a.classid=1 and a.nclassid=1;

//解读

插入到 表2(栏1,栏2,栏3,栏4)

选择 别名a.栏1, 别名a.栏2, 别名a.栏3, 别名d.栏4 加上 别名c.栏5


(表1 别名a 左连接 (表3 别名c 左连接 表4 别名d 在 别名c.栏2 等于 别名d.栏2) 在 别名a.栏2 等于 别名c.栏2 和
别名a.栏3=别名c.栏3) 左连接 表2 别名b 在 别名a.栏1 等于 别名b.栏1 在那里 别名a.栏2=1 和 别名a.栏3=1

连接两个表, 并追加数据到其中一个表

insert into cttag(articleid,classid,nclassid)

select a.articleid,a.classid,a.nclassid

from ctarticle as a left join
cttag as b on a.articleid = b.articleid where a.classid=1 and a.nclassid=1;

//解读

插入到 表2(栏1,栏2,栏3)

选择 别名a.栏1, 别名a.栏2, 别名a.栏3

从 表1 别名a 左连接
表2 别名b 在 别名a.栏1 等于 别名b.栏1 在那里 别名a.栏4=1 和 别名a.栏5=1

左连接

同步两表的数据

update ctarticle a inner join cttag b on a.articleid = b.articleid set
b.classid=a.classid, b.nclassid=a.nclassid;

//解读

更新 表1 别名a 联接 表2 别名2
在 别名a.栏1 等于 别名b.栏1 设置 别名b.栏2 更新为 别名a.栏2, 别名b.栏3 更新为 别名a.栏3

右外连接

select a.*, b.* from bunclass a right join ctclass b on a.classid=b.classid
where a.nclassid=20

查询别名 a,b 表, 只匹配 b 表中的内容.

添加数据到连接表之一

insert into cttag ( tag, articleid ) select top 1 b.tag, a.articleid from
ctarticle as a left join cttag as b on a.articleid = b.articleid where
a.articleid order by a.articleid desc;

变通中的用法二

insert into bureply

select b.*, a.classid, a.nclassid

from article as a inner join reply as
b on a.articleid = b.articleid

where classid=50;

实际应用中的变通

insert
into butag ( tag, articleid, classid, nclassid)

select b.tag, a.articleid,
a.classid, a.nclassid

from article as a inner join tag as b on a.articleid =
b.articleid

where classid=24;

添加数据到其他表

insert into butag (
tag, articleid )

select b.tag, a.articleid

from article as a inner join
tag as b on a.articleid = b.articleid

where a.articleid<>false;

//解读

添加到 接收表(列1,列2)

选择 别名b.列1, 别名a.列2

从 表1 表名a 联接 表2 表名b 在
别名a.列c 等于 别名b.列c

在哪里 别名a.列c 不等于 没有

实际应用中的变通

select b.tag,
a.articleid, a.classid, a.nclassid

from article as a inner join tag as b on
a.articleid = b.articleid

where a.classid=24;

查询

select b.tag,
a.articleid

from article as a inner join tag as b on a.articleid =
b.articleid

where a.articleid<>false;

//解读

选择 别名b.列, 别名a.列

从 表1 别名a 联接 表2 别名b 在 别名a.列c = 别名b.列c

在哪里 别名a.列c 不等于 没有

注: as
不是必要
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐