数据库表的连接⽤法详解(join)
连接查询
通过连接运算符可以实现多个表查询。连接是关系数据库模型的主要特点,也是它区别于其它类型数据库管理系统的⼀个标志。
在关系数据库管理系统中,表建⽴时各数据之间的关系不必确定,常把⼀个实体的所有信息存放在⼀个表中。当检索数据时,通过连接操作查询出存放在多个表中的不同实体的信息。连接操作给⽤户带来很⼤的灵活性,他们可以在任何时候增加新的数据类型。为不同实体创建新的表,尔后通过连接进⾏查询。
连接可以在SELECT 语句的FROM⼦句或WHERE⼦句中建⽴,似是⽽⾮在FROM⼦句中指出连接时有助于将连接操作与WHERE⼦句中的搜索条件区分开来。所以,在Transact-SQL中推荐使⽤这种⽅法。
SQL-92标准所定义的FROM⼦句的连接语法格式为:
FROM join_table join_type join_table
[ON (join_condition)]
其中join_table指出参与连接操作的表名,连接可以对同⼀个表操作,也可以对多表操作,对同⼀个表操作的连接⼜称做⾃连接。
join_type 指出连接类型,可分为三种:内连接、外连接和交叉连接。
内连接(INNER JOIN)使⽤⽐较运算符进⾏表间某(些)列数据的⽐较操作,并列出这些表中与连接条件相匹配的数据⾏。根据所使⽤的⽐较⽅式不同,内连接⼜分为等值连接、⾃然连接和不等连接三种。
外连接分为左外连接(LEFT OUTER JOIN或LEFT JOIN)、右外连接(RIGHT OUTER JOIN或RIGHT JOIN)和全外连接(FULL OUTER JOIN或FULL JOIN)三种。与内连接不同的是,外连接不只列出与连接条件相匹配的⾏,⽽是列出左表(左外连接时)、右表(右外连接时)或两个表(全外连接时)中所有符合搜索条件的数据⾏。
交叉连接(CROSS JOIN)没有WHERE ⼦句,它返回连接表中所有数据⾏的笛卡尔积,其结果集合中的数据⾏数等于第⼀个表中符合查询条件的数据⾏数乘以第⼆个表中符合查询条件的数据⾏数。
连接操作中的ON (join_condition) ⼦句指出连接条件,它由被连接表中的列和⽐较运算符、逻辑运算符等构成。
⽆论哪种连接都不能对text、ntext和image数据类型列进⾏直接连接,但可以对这三种列进⾏间接连接。
例如:
SELECT p1.pub_id,p2.pub_id,p1.pr_info
FROM pub_info AS p1 INNER JOIN pub_info AS p2
ON DATALENGTH(p1.pr_info)=DATALENGTH(p2.pr_info)
(⼀)内连接
内连接查询操作列出与连接条件匹配的数据⾏,它使⽤⽐较运算符⽐较被连接列的列值。内连接分三种:
1、等值连接:在连接条件中使⽤等于号(=)运算符⽐较被连接列的列值,其查询结果中列出被连接表中的所有列,包括其中的重复列。
2、不等连接:在连接条件使⽤除等于运算符以外的其它⽐较运算符⽐较被连接的列的列值。这些运算符包括>、>=、<=、<、!>、!<;和<>。
3、⾃然连接:在连接条件中使⽤等于(=)运算符⽐较被连接列的列值,但它使⽤选择列表指出查询结果集合中所包括的列,并删除连接表中的重复列。
例,下⾯使⽤等值连接列出authors和publishers表中位于同⼀城市的作者和出版社:
SELECT *
FROM authors AS a INNER JOIN publishers AS p
ON a.city=p.city
⼜如使⽤⾃然连接,在选择列表中删除authors 和publishers 表中重复列(city和state):
SELECT a.*,p.pub_id,p.pub_untry
FROM authors AS a INNER JOIN publishers AS p
ON a.city=p.city
(⼆)外连接
内连接时,返回查询结果集合中的仅是符合查询条件( WHERE 搜索条件或 HAVING 条件)和连接条件的⾏。⽽采⽤外连接时,它返回到查询结果集合中的不仅包含符合连接条件的⾏,⽽且还包括左表(左外连接时)、右表(右外连接时)或两个边接表(全外连接)中的所有数据⾏。
如下⾯使⽤左外连接将论坛内容和作者信息连接起来:
SELECT a.*,b.* FROM luntan LEFT JOIN usertable as b
ON a.username=b.username
下⾯使⽤全外连接将city表中的所有作者以及user表中的所有作者,以及他们所在的城市:
SELECT a.*,b.*
FROM city as a FULL OUTER JOIN user as b
ON a.username=b.username
(三)交叉连接
交叉连接不带WHERE ⼦句,它返回被连接的两个表所有数据⾏的笛卡尔积,返回到结果集合中的数据⾏数等于第⼀个表中符合查询条件的数据⾏数乘以第⼆个表中符合查询条件的数据⾏数。
例,titles表中有6类图书,⽽publishers表中有8家出版社,则下列交叉连接检索到的记录数将等
于6*8=48⾏。
SELECT type,pub_name
FROM titles CROSS JOIN publishers
ORDER BY type
两个主要的连接类型是内连接和外连接。到⽬前为⽌,所有⽰例中使⽤的都是内连接。内连接只保留交叉积中满⾜连接条件的那些⾏。如果某⾏在⼀个表中存在,但在另⼀个表中不存在,则结果表中不包括该信息。
外连接是内连接和左表和/或右表中未包括内连接中的那些⾏的并置。当对两个表执⾏外连接时,可任意将⼀个表指定为左表⽽将另⼀个表指定为右表。外连接有三种类型:
左外连接包括内连接和左表中未包括在内连接中的那些⾏。
右外连接包括内连接和右表中未包括在内连接中的那些⾏。
全外连接包括内连接以及左表和右表中未包括在内连接中的⾏。
内连接⼀般是检索两个表⾥连接字段都存在的数据。
左连接的意思是,查询左(语句前⾯)表⾥的所有内容,⽆论右边表⾥有没有。右边表⾥没有的内容⽤NULL代替。
右连接和左连接相反。
数据表的连接有:
1、内连接(⾃然连接): 只有两个表相匹配的⾏才能在结果集中出现
2、外连接: 包括
(1)左外连接(左边的表不加限制)
(2)右外连接(右边的表不加限制)
(3)全外连接(左右两表都不加限制)
sql left join 多表连接3、⾃连接(连接发⽣在⼀张基表内)
⼀.先看⼀些最简单的例⼦
例⼦
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.lassid
where a.classid=23 lassid=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) lassid = 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,
更新操作
左连接中数据的筛选
insert into cttag(articleid,classid,nclassid) select a.articleid,a.lassid 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
显⽰⽂章表中的全部, 调⽤类别表中的栏⽬
select a.*, b.*, c.* from (ctarticle a left join ctclass b on a.classid=b.classid) left join ctnclass c lassid
//作⽤, 有时在⽂章表中包含了在个别类别表中没有的数据, ⽤这个语法可以读出⽂章表的全部数据
//a 为⽂章表, b 为主类别, c 为⼦类别
同上例, 选择追加数据时加上空格
insert into cttag(articleid,classid,nclassid,tag) select a.articleid,a.lassid,d.class+' '+c.nclass
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论