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

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

但是学的很浅

现在要用到了

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

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

都是干什么用的啊?

谢谢大家

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

我想有空的时候看看
...全文
426 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
看看这个~~
内容概要:本文提出了一种基于蒙特卡洛模拟与拉格朗日松弛法的散式优化策略,用于解决电动汽车充电站在时电价机制下的有序充电调度问题。通过蒙特卡洛方法模拟电动汽车充电行为的随机性,生成多样化负荷场景,构建以降低电网负荷波动和用户充电成本为目标的优化模型;采用拉格朗日松弛法对耦合约束进行解耦,实现布式求解,在保障用户隐私的同时提升计算效率。文中设计了详细的仿真场景,系统析了该调度策略对电网负荷特性和用户经济性的影响,验证了所提方法在实际应用中的有效性与可行性。; 适合人群:具备电力系统运行、优化算法理论及Matlab编程能力的研究生、科研人员以及从事智能电网与电动汽车相关领域的工程技术人员。; 使用场景及目标:①应用于城市规模化充电站集群的有序充电管理,实现电网“削峰填谷”;②为电力公司制定科学合理的时电价政策提供量化析工具;③支撑智能电网中需求侧资源的布式协同优化调度研究与系统设计。; 阅读建议:建议结合提供的Matlab代码深入理解算法实现流程,重点掌握蒙特卡洛场景生成机制与拉格朗日松弛迭代求解过程,可通过调整参数设置复现不同工况下的仿真结果,以深化对散式优化机制与调度效果之间关系的理解。
内容概要:本文研究了基于元胞神经网络配流与DQN强化学习的公交线网扰动韧性恢复方法,旨在应对公共交通系统中突发事件导致的网络扰动问题。通过结合元胞神经网络对交通流量进行精细化建模与配,并利用深度Q网络(DQN)强化学习算法动态优化调度策略,实现公交线路在扰动后的快速恢复与运力再配。研究构建了完整的仿真框架,在Matlab平台上实现了算法的编码与测试,验证了所提方法在提升公交系统韧性、减少乘客延误和优化资源利用方面的有效性。; 适合人群:具备一定交通工程、智能算法或强化学习基础,从事智慧交通、城市公交调度、韧性城市等方向研究的研究生、科研人员及工程技术开发者。; 使用场景及目标:①应用于城市公交系统在遭遇突发事件(如道路封闭、车辆故障、极端天气)时的应急调度与恢复决策;②为智能交通系统(ITS)提供基于AI的动态配流与优化控制方案;③推动强化学习在复杂交通网络管理中的落地实践; 阅读建议:建议读者结合Matlab代码深入理解算法实现细节,重点关注元胞神经网络的状态转移机制与DQN奖励函数的设计逻辑,并可通过调整扰动场景参数进行仿真实验,以掌握模型的适应性与优化潜力。

17,377

社区成员

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

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