请高手解答几个sql的join的问题的疑惑。我用的是MSSqlserver。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了请高手解答几个sql的join的问题的疑惑。我用的是MSSqlserver。相关的知识,希望对你有一定的参考价值。

要使两个表支持join,有什么条件吗?比如说是否必须定义外键?是否字段名必须一致?
left outer join和 right outer join的区别到底是什么?我用northwind数据库,其中两个表[orders]800多行和[Order Details]2100多行 有一对多的外键关系。为什么我下面的语句不管是left 还是 right 还是inner join都是一样多的行数?也就是[Order Details]的行数?
针对上述两个表,用什么语句才能体现出left 还是 right 还是inner的区别?请写具体语句。
select o.orderid as oid , od.OrderID as odid
from orders o left join [Order Details] od
on o.OrderID = od.OrderID

两个表join,没有什么条件。不一定要定义外键,字段名也不一定要一致。

inner join 和 left join 的区别在于:如果左表中的某行记录在右表中没有找到匹配行,那么inner join中将不出现该行,而left join中仍将保留这行记录。因此,如果左表中每一行数据都能在右表中找到匹配行,inner join 和 left join的行数将相同。

同理如果右表中每一行数据都能在左表中找到匹配行,inner join 和 right join的行数将相同。

具体到你的例子,不管是left 还是 right 还是inner join都等于[Order Details]的行数,说明左表[orders]和右表[Order Details]严格遵循了一对多关系,即每一条order对应一条或多条Detail;每一条Detail只对应一条order。

对于这么完美的数据,无论怎么join,都不会有区别的。如果非要看区别的话,可以只在orders表中新加一条数据,此时left join的行数会比inner join多1。追问

说得好,可惜迟了。

参考技术A 1,可以有条件,也可以无条件,但是如果无条件的话有时没什么意义,字段名不必一致,也不一定需要外键,外键仅仅是个约束条件而已
举例说明
有条件的就不说了,比如无条件的
有一个楼号表
比如
1号楼
2号楼
3号楼

还有个单元表,每个楼有3个单元
1单元
2单元
3单元

现在要用这个表构造出所有的楼的单元

select * from 楼表,单元表
结果就是
1号楼 1单元
1号楼 2单元
1号楼 3单元
。。。
3号楼 3单元
共9条记录

left outer join和 right outer join的区别
比如两个表
学生表
学号 姓名
1 张三
2 李四
3 王五

成绩表
学号 成绩
1 100
2 90

但是可能王五没来参加考试,所以看不出成绩,但是我们想让王五的成绩如果没有就显示0
那么
select 学生表.姓名,isnull(成绩表.成绩,0) from 学生表 left join 成绩表 on 学生表.学号=成绩表.学号

其实left join 和 left out join是一样的,只是个简写的问题,不要太在意,这样就是说,以学生表为左表,也就是主表(因为这里的姓名是全的)用它来左连成绩表,就能把所有参加与未参加考试的人成绩列出来,isnull你也不必太在意,就是如果那个成绩为空,就显示0,否则王五的成绩就显示成null了,right join基本同理,

select 学生表.姓名,isnull(成绩表.成绩,0) from 成绩表 right join 学生表 on 学生表.学号=成绩表.学号

是以在后边的表为主表

最后一个问题,你语句刚看到
如果你用几种方式看到的结果都一样,那么用上边的例子来说,就是所有人都参加考试了
用你的表来说就是,每个订单表在订单明细中都有相应的记录追问

我后来补充了,麻烦你再看看?麻烦你不要说什么学生表,就用我上面的那两个表吧。

追答


比如,你上边两个表
你orders表里的那个orderid在orderdetail表中都有相应的记录,你可以用语句查一下

select * from [Order Details] where orderid not in (select OrderID from orders)

select * from Orders where orderid not in (select OrderID from [Order Details])

这两个查询是不是都没有记录,如果没有记录就说明你明细表里所有的orderid都能和orders表里的orderid关联上

追问

这个我最先查过的,都没有记录的。确保是一对多的关系。

追答

肯定是一对多或一对一啊
但是如果存在在orders表里有,而orderdetail里没有的情况,这个时候你的left join 和 inner join的效果你就看出来了
left join 是把在orders表中有的都列出来,即使orders表里有,而orderdetail里没有,也会列出,只是没关联上的那些条,会显示成空值
而 inner join 只会列出来两个表关联字段相等的,也就是o.OrderID = od.OrderID

追问

谢了,不过我采纳的那个帮忙远程看了。你的还是很详细。

参考技术B 1、join只有一个条件,就是要符合on关联的条件,此外什么都没限制
2、left join与right join却别就如字面意思,left-right,左外部连接简称左连接,它是以join左侧表为主表,右侧为辅表,right右连接则相反,仅有这一点区别
3、northwind作为事例数据库,它的数据是很规范的,也就是说,order.orderid在orderdetais表中必然有与之相关联的数据,而outer join与inner join的主要区别就在于:outer join可以输出主表的全部数据以及辅表中与主表匹配的数据(匹配条件就是on的条件),辅表不匹配的数据会用null值占位;而join则不分主辅表,会输出join两表的全部匹配数据
结合你的表,除非出现orders.orderid在details表中不存在的现象(或者反过来),才会体现出outer join与join的区别追问

很好,但是迟了点。

追答

呵呵自家人何必客气

追问

哈哈,确实确实!

参考技术C LEFT OUTER JOIN 和RIGHT OUTER JOIN 的区别在于匹配的源数据是哪个方向,比如A LEFT JOIN ON B 这样,如果B表内匹配不到A表的数据,那B表相应行为空,比如

A有字段 B表
ID 名称 ID 待遇
1 男 1 100
2 女 2 200
3 男
SELECT * FROM A LEFT JOIN B ON A.ID=B.ID
ID 名称 ID 待遇
1 男 1 100
2 女 2 200
3 男 NULL NULL
如果
SELECT * FROM B LEFT JOIN A ON B.ID=A.ID
ID 待遇 ID 名称
1 100 1 男
2 200 2 女
因为B表是源表,ON是ID,就是ID匹配。

SELECT * FROM A INNER JOIN B ON A.ID=B.ID
ID 名称 ID 待遇
1 男 1 100
2 女 2 200
因为B表没有对应A的组元,所以无法匹配到A里ID=3的字段,意思就是INNER 会删除没有匹配的数据行,只保留有匹配的数据行

字段名可以不一样,还可以在字段名里使用函数
比如把B表的ID修改为 AD
那样就是ON A.ID=B.AD
如果B表的相应字段需要进行函数才能得到相应值,那样就在ON的时候使用函数进行加工数据
比如 A.ID=B.ID+’1'这样的方式本回答被提问者采纳

高手进!关于Quartus仿真的疑惑。相当不解呀!

最近看一本介绍Quartus ii的书,上面讲的还挺好,但是有关于仿真的几个问题我一直没搞清楚,希望懂这方面的朋友讲讲。主要是Analyze Current file,Start Compilation,Start Analysis&Synthesis和Start Analysis&Elaboration之间的关系。
首先是Analyze Current file,它的意思应该就是分析当前文件。当我们在Quartus上输入程序之后通常会用到“Analyze Current file”。我的理解就是:Analyze Current file的功能就是单单对所输入的程序进行语法检查,除此之外没有其他的作用。不知道是不是这样理解?如果是这样的话,那么能不能用Start Analysis&Elaboration代替呢?或者有其他的俩个代替。
第二:在分配引脚之前必须对设计进行分析及语法检查,也就是要用到Start Analysis&Elaboration。那么Start Analysis&Elaboration的作用和其他三个有何不同,用它进行检查之后生成的是什么文件?在分配引脚之前一定得用到它吗?
第三:Start Compilation。意思就是编译。编译什么?是像硬件语言的编译那样将VHDL或VerilogHDL编译成可以识别的机器代码吗?什么情况下才会用到它?
第四:Start Analysis&Synthesis。分析综合,是不是就是将你的VHDL或VerilogHDL翻译成具体的器件所构成的电路图?什么情况下才会用到它?
第五:波形仿真,Start Simulation。这个问题比较纠结。仿真的时候出错,说:“Aun Analysis and Synthesis through Technology Mapping followed by Timing Analyzer...”,原因是波形仿真之前得进行Start Analysis&Synthesis,也就是分析综合。然后我就照做,仿真任然出错:“can't continue timing simulation because delay annotation information for design missing”。之后我就按照书上的一步一步地来,用Start Compilation进行编译,而不是用的Start Analysis&Synthesis。结果波形仿真的时候没有一个错误,直接出结果。然后我立马用Start Analysis&Synthesis后再进行波形仿真,结果仍出现上述错误。难道波形仿真之前应该用Start Compilation而不是Start Analysis&Synthesis?但当波形仿真出错,我用Quartus里面的帮助查询的时候,它提示就是用到分析综合之后再波形仿真呀?
请回答的高手针对我的问题逐一进行解答,大谢!!!

参考技术A 问题好多啊。
QuartusII仿真步骤:
1.编译设计Start Compilation(包括:综合(vlog、vhd 转换成电路),布线(映射到具体器件上))
2.建立波形文件(激励)
3.开始仿真Start Simulation
4.得到仿真结果
QuartusII 10.0之后自带的仿真工具已经没有了,建议使用Modelsim(专业的仿真工具)本回答被提问者采纳

以上是关于请高手解答几个sql的join的问题的疑惑。我用的是MSSqlserver。的主要内容,如果未能解决你的问题,请参考以下文章

求高手解答下关于“危机公关”的疑惑

求高手帮帮忙! 怎么使用Ueditor上传图片? 我用的是php,请高手给个demo, 谢谢!

请高手指点:我用的是“雨林木风”精简版的XP系统,

Winform进度条的问题,请高手指点

关于SQL Server 2000 Varchar长度的一个问题!!请高手解答

网页高手请进!!