(100分求教)数据库简单问题,为什么用外连接、内连接等等

clarck_913 2008-12-24 04:03:31
小弟以前学习过数据库

但是学的很浅

现在要用到了

想问个问题,在查询的时候为什么要分外连接,内连接啊?

外连接还有左外连接和右外连接

都是干什么用的啊?

谢谢大家

另外请推荐本Oracle的入门教材

我想有空的时候看看
...全文
381 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
pobaby 2008-12-25
  • 打赏
  • 举报
回复
google baidu 搜一下就有了。
给你转一个。
如下:

(注:outer的意思就是"没有关联上的行"。)

1.cross join 全外连接(笛卡尔乘积)

SELECT A.*, B.* FROM A FULL OUTER JOIN B ON A.ID = B.ID

2.inner join 内连接(在笛卡尔乘积的结果集中去掉不符合连接条件的行)

SELECT A.* FROM A INNER JOIN B ON A.ID=B.ID

3.left outer join 左外连接(在inner join的结果集上加上左表中没被选上的行,行的右表部分每个字段都用NUll填充)

SELECT A.* FROM A LEFT JOIN B ON A.ID = B.ID

4.right outer join 右外连接(在inner join的结果集上加上右表中没被选上的行,行的左表部分全用NULL填充。)

SELECT A.* FROM A RIGHT JOIN B ON A.ID = B.ID

——THE END——

<<<<<<<<<<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并不以谁为基础,它只显示符合条件的记录


1、join 产生的是笛卡尔积。
2、union 会排除重复的记录
3、union all 不会排除重复的记录


Oracle对Oracle9i SQL 做了一些很重要的改进,包括一些令人兴奋的新特点,支持1:5的数量级和ISO99中的SQL标准。作为Oracle的补充,它包括以下新的TABLE JOIN的句法结构:
  CROSS IN——它在两个表格中创建了一个卡迪尔列,就象是在Oracle8i中没写WHERE时那样。
  NATURAL JOIN——这是一个很有用的Oracle9i的句法,它通过从WHERE子句中移动连接标准来改善SQL的稳定性
  USING子句——它可以通过名字来具体指定连接
  ON子句——这个句法允许在两个表格中为连接具体指定栏目的名头
   LEFT OUTER JOIN——它返回表格中左边的行和右边的数值,如果没有搭配的行的话,则返回零
  RIGHT OUTER JOIN——它返回表格中右边的行和左边的数值,如果没有搭配的行的话,则返回零
  FULL OUTER JOIN——它返回的是两个表格中所有的行,用零填满每一个空格。这在Oracle8i中则没有相应的此种句法
  大多数改进都是为了让那些非Oracle的请求以快速的进入Oracle数据库而引进的,并且必须记住这些只是句法上的不同,ISO99标准并没有给Oracle9i SQL带来任何新的功能。
  The CROSS JOIN
  在Oracle中,CROSS JOIN产生了一个“卡迪尔的产物(Cartesian product)”,就象是在连接两个表格时忘记加入一个WHERE子句一样
  select last_name,dept_id
  from emp,depts;
  在Oracle9i中,我们使用CROSS JOIN 来达到相同的结果
  select last_name.dept_id
  from emp
  CROSS JOIN dept;
  NATURAL JOIN
  我喜欢NATURAL JOIN的原因在于它能够通过在两个表格中配对的栏目的名头来自动的检查join。它同时还简化了Oracle9i SQL,由于where子句仅仅只能过滤谓语,当然,NATURAL JOIN要求在每一个表格中的栏目的名字相同。很有意思的是,这种特性甚至在没有主要的或是外来的关键词作为参考是也能起作用
  Oracle8i,
  Select book_title, sum(quantity)
  From book, sales
  Where book.book_id = sales.book_id
  group by book_title;
  Oracle9i
  Select book_title, sum(quantity)
  from book
  natural join sales
  group by book_title;
  USING子句
  假如几个栏目有同样的名字,而你又不想用所有的这些栏目来连接的时候,你就可以用USING子句。在USING子句中所列的栏目的句子中不会有任何的修饰词,包括where子句也不会有
  Oracle8i
  select dept_id, city
  from departments, locations
  where departments.location_id = location.location_id;
  Oracle9i
  select department_name, city
  from departments
  JOIN locations
  USING (location_id);
  ON子句
  ON子句被用于当在两个表格中的栏目名字不搭配时来连接表格。而连接条件就是where子句中的过滤条件
  Oracle8i
  select department_name, city
  from department, location
  where department.location_id = location.loc_id;
  Oracle9i
  select department_name, city
  from department d
  JOIN location l
  ON (d.location_id = l.id);
  易变的连接
  易变的连接就是两个以上的表格被连接所用的。ISO SQL 1999标准通常假设表格从左至右连接,连接的条件是能够为现在的连接或以前的与左边的连接相关联的栏目提供参考。
  Oracle8i
  select emp_id, city_name, dept_name
  from location l, department d, emp e
  where d.location_id = l.location_id
  and d.department_id = e.department_id;
  Oracle9i
  select emp_id, city_name, dept_name
  from locations l
  JOIN departments d ON (d.location_id = l.location_id)
  JOIN employees e ON (d.department_id = e.department_id);

  新的OUTER JOIN句法
  ISO99标准把复杂的加号从Oracle outer join中拿出去,并使得outer join SQL更容易理解。
  LEFT OUTER JOIN
  在LEFT OUTER JOIN中,会返回所有左边表格中的行,甚至在被连接的表格中没有可配对的栏目的情况下也如此。在下边的例子中,返回了所有雇员的姓,甚至包括了那些没有分配到部门的雇员。
  Oracle8i
  select last_name, dept_id
  from emp e, dept d
  where e.department_id = d.department_id(+);
  Oracle9i
  select last_name, dept_id
  from emp
  LEFT OUTER JOIN Dept
  ON e.dept_id = d.dept_id;

  RIGHT OUTER JOIN
  在RIGHT OUTER JOIN中返回的是表格中所有右边的行,甚至在被连接的表格中没有可配对的栏目的情况下也如此。在这个例子中,返回了所有部门的ID,包括那些没有一个雇员的的部门。
  Oracle8i
  select last_name, d.dept_id
  from employees e, departments d
  where e.department_id(+) = d.department_id;
  Oracle9i
  select last_name, d.dept_id
  from employees e
  RIGHT OUTER JOIN departments d
  ON (e.department_id = d.department_id);
  总结
  ISO99标准是Oracle改进SQL工具的另一个例子。NATURAL JOIN LEFT OUTER JOIN 和 RIGHT OUTER JOIN是这些改进中最受欢迎的,它们分别简化了SQL句法以及消除了对于复杂句法(比如+)的需要。
xingkongmori 2008-12-25
  • 打赏
  • 举报
回复
在百度里Google一下就全出来了
icss_zhen 2008-12-24
  • 打赏
  • 举报
回复
4楼的例子好,简单易懂!!很有说服力,赞一个,呵~~
hnjhjzyyxgs 2008-12-24
  • 打赏
  • 举报
回复

aqiangjx
内连接和外连接区别
在之前,我对MSSQL中的内连接和外连接所得出的数据集不是很清楚。这几天重新温习了一下SQL的书本,现在的思路应该是很清楚了,现在把自己的理解发出来给大家温习下。希望和我一样对SQL的连接语句不太理解的朋友能够有所帮助。(发这么菜的教程,各位大大们别笑话偶了,呵:D )

有两个表A和表B。
表A结构如下:
Aid:int;标识种子,主键,自增ID
Aname:varchar

数据情况,即用select * from A出来的记录情况如下图1所示:


图1:A表数据

表B结构如下:
Bid:int;标识种子,主键,自增ID
Bnameid:int

数据情况,即用select * from B出来的记录情况如下图2所示:



图2:B表数据

为了把Bid和Aid加以区分,不让大家有误解,所以把Bid的起始种子设置为100。
有SQL基本知识的人都知道,两个表要做连接,就必须有个连接字段,从上表中的数据可以看出,在A表中的Aid和B表中的Bnameid就是两个连接字段。
下图3说明了连接的所有记录集之间的关系:



图3:连接关系图

现在我们对内连接和外连接一一讲解。
1.内连接:利用内连接可获取两表的公共部分的记录,即图3的记录集C
语句如下:Select * from A JOIN B ON A.Aid=B.Bnameid
运行结果如下图4所示:



图4:内连接数据

其实select * from A,B where A.Aid=B.Bnameid与Select * from A JOIN B ON A.Aid=B.Bnameid的运行结果是一样的。
2.外连接:外连接分为两种,一种是左连接(Left JOIN)和右连接(Right JOIN)
(1)左连接(Left JOIN):即图3公共部分记录集C+表A记录集A1。
语句如下:select * from A Left JOIN B ON A.Aid=B.Bnameid
运行结果如下图5所示:



图5:左连接数据

说明:
在语句中,A在B的左边,并且是Left Join,所以其运算方式为:A左连接B的记录=图3公共部分记录集C+表A记录集A1
在图3中即记录集C中的存在的Aid为:2 3 6 7 8
图1中即表A所有记录集A中存在的Aid为:1 2 3 4 5 6 7 8 9
表A记录集A1中存在的Aid=(图1中即A表中所有Aid)-(图3中即记录集C中存在的Aid),最终得出为:1 4 5 9
由此得出图5中A左连接B的记录=图3公共部分记录集C+表A记录集A1,
最终得出的结果图5中可以看出Bnameid及Bid非NULL的记录都为图3公共部分记录集C中的记录;Bnameid及Bid为NULL的Aid为1 4 5 9的四笔记录就是表A记录集A1中存在的Aid。

(2)右连接(Right JOIN):即图3公共部分记录集C+表B记录集B1。
语句如下:select * from A Right JOIN B ON A.Aid=B.Bnameid
运行结果如下图6所示:



图6:右连接数据

说明:
在语句中,A在B的左边,并且是Right Join,所以其运算方式为:A右连接B的记录=图3公共部分记录集C+表B记录集B1
在图3中即记录集C中的存在的Aid为:2 3 6 7 8
图2中即表B所有记录集B中存在的Bnameid为:2 3 6 7 8 11
表B记录集B1中存在的Bnameid=(图2中即B表中所有Bnameid)-(图3中即记录集C中存在的Aid),最终得出为:11
由此得出图6中A右连接B的记录=图3公共部分记录集C+表B记录集B1,
最终得出的结果图6中可以看出Aid及Aname非NULL的记录都为图3公共部分记录集C中的记录;Aid及Aname为NULL的Aid为11的记录就是表B记录集B1中存在的Bnameid。

总结:

通过上面的运算解说,相信很多人已经想到,上面的情况(包括图3的关系图)说明的都只是A在B的左边的情况,
以下语句B在A的右边的又会出现什么情况呢??
select * from B Left JOIN A ON A.Aid=B.Bnameid
select * from B Right JOIN A ON A.Aid=B.Bnameid

其实对图3左右翻转一下就可以得出以下结论:
select * from B Left JOIN A ON A.Aid=B.Bnameid和select * from A Right JOIN B ON A.Aid=B.Bnameid所得出的记录集是一样的

select * from B Right JOIN A ON A.Aid=B.Bnameid和select * from A Left JOIN B ON A.Aid=B.Bnameid所得出的记录集也是一样的。
posted on 2008-03-20 17:06 秋枫故事 阅读(215) 评论(1) 编辑 收藏
sleepzzzzz 2008-12-24
  • 打赏
  • 举报
回复
多实验,看多了文字你会发晕的.
rexyudl 2008-12-24
  • 打赏
  • 举报
回复
因为你需要内联接或外联接之后的结果!再简单点就是业务需要用!
taotie1225 2008-12-24
  • 打赏
  • 举报
回复
具体例子都有了,强悍地,看下sql帮助里的join
范佩西_11 2008-12-24
  • 打赏
  • 举报
回复
给你个笔记
inner join、 left join 、right join、 outer join之间的区别
A表(a1,b1,c1) B表(a2,b2)
a1 b1 c1 a2 b2
01 数学 95 01 张三
02 语文 90 02 李四
03 英语 80 04 王五
select A.*,B.* from A
inner join B on(A.a1=B.a2)
结果是:
a1 b1 c1 a2 b2
01 数学 95 01 张三
02 语文 90 02 李四

select A.*,B.* from A
left outer join B on(A.a1=B.a2) 相当于 select a.*,b.* from a,b where a.id=b.id(+)左链接
结果是:
a1 b1 c1 a2 b2
01 数学 95 01 张三
02 语文 90 02 李四
03 英语 80 NULL NULL

select A.*,B.* from A
right outer join B on(A.a1=B.a2) select a.*,b.* from a,b where a.id(+)=b.id右链接
结果是:
a1 b1 c1 a2 b2
01 数学 95 01 张三
02 语文 90 02 李四
NULL NULL NULL 04 王五

select A.*,B.* from A
full outer join B on(A.a1=B.a2)
结果是:
a1 b1 c1 a2 b2
01 数学 95 01 张三
02 语文 90 02 李四
03 英语 80 NULL NULL
NULL NULL NULL 04 王五
又是违规昵称 2008-12-24
  • 打赏
  • 举报
回复
内连接:若连接的结果集中只保留了符合连接条件的元组,而排除了两个表中没有对应的或匹配的元组情况,这种连接称为内连接。在内连接的查询结果中,会丢失一部分信息。

外连接:如果要求查询结果集中保留非匹配的元组,则为外连接。
左外连以左边为准,右边不存在补空;
右外连同理
yf520gn 2008-12-24
  • 打赏
  • 举报
回复
http://www.5qcn.net/info/804.htm
GOOGLE上搜JOIN的用法,实在太多了·
yf520gn 2008-12-24
  • 打赏
  • 举报
回复
http://www.cublog.cn/u/25102/showart_187203.html
看看这个~~

17,377

社区成员

发帖
与我相关
我的任务
社区描述
Oracle 基础和管理
社区管理员
  • 基础和管理社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧