多表关联查询多条件级联查询等等一对多多对多。

时间:2013-7-11    作者:悬浮的青春    分类: .net相关


最近工作中用到了好多带外键和级联关系的多表组合查询。感觉这点不是很熟。收集 了下相关资料。先学习下。。。

 

 

 

 

inner join(等值连接) 只返回两个表中联结字段相等的行   left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录 INNER JOIN 语法:  INNER JOIN 连接两个数据表的用法:   SELECT * FROM 表1 INNER JOIN 表2 ON 表1.字段号=表2.字段号 INNER JOIN 连接三个数据表的用法:   SELECT * FROM (表1 INNER JOIN 表2 ON 表1.字段号=表2.字段号) INNER JOIN 表3 ON 表1.字段号=表3.字段号  INNER JOIN 连接四个数据表的用法:   SELECT * FROM ((表1 INNER JOIN 表2 ON 表1.字段号=表2.字段号) INNER JOIN 表3 ON 表1.字段号=表3.字段号) INNER JOIN 表4 ON Member.字段号=表4.字段号 INNER JOIN 连接五个数据表的用法:   SELECT * FROM (((表1 INNER JOIN 表2 ON 表1.字段号=表2.字段号) INNER JOIN 表3 ON 表1.字段号=表3.字段号) INNER JOIN 表4 ON Member.字段号=表4.字段号) INNER JOIN 表5 ON Member.字段号=表5.字段号  连接六个数据表的用法:略,与上述联接方法类似,大家举一反三吧:) 注意事项:  在输入字母过程中,一定要用英文半角标点符号,单词之间留一半角空格; 在建立数据表时,如果一个表与多个表联接,那么这一个表中的字段必须是“数字”数据类型,而多个表中的相同字段必须是主键,而且是“自动编号”数据类型。否则,很难联接成功。 代码嵌套快速方法:如,想连接五个表,则只要在连接四个表的代码上加一个前后括号(前括号加在FROM的后面,后括号加在代码的末尾即可),然后在后括号后面继续添加“INNER JOIN 表名X ON 表1.字段号=表X.字段号”代码即可,这样就可以无限联接数据表了:)    1.理论  只要两个表的公共字段有匹配值,就将这两个表中的记录组合起来。 个人理解:以一个共同的字段求两个表中符合要求的交集,并将每个表符合要求的记录以共同的字段为牵引合并起来。 语法  select * FROM table1 INNER JOIN table2 ON table1 . field1 compopr table2 . field2 INNER JOIN 操作包含以下部分: 部分 说明 table1,  table2 要组合其中的记录的表的名称。  field1,field2 要联接的字段的名称。如果它们不是数字,则这些字段的数据类型必须相同,并且包含同类数据,但是,它们不必具有相同的名称。  compopr 任何关系比较运算符:“=”、“<”、“>”、“<=”、“>=”或者“<>”。 说明  可以在任何 FROM 子句中使用 INNER JOIN 操作。这是最常用的联接类型。只要两个表的公共字段上存在相匹配的值,Inner 联接就会组合这些表中的记录。  可以将 INNER JOIN 用于 Departments 及 Employees 表,以选择出每个部门的所有雇员。而要选择所有部分(即使某些部门中并没有被分配雇员)或者所有雇员(即使某些雇员没有分配到任何部门),则可以通过 LEFT JOIN 或者 RIGHT JOIN 操作来创建外部联接。 如果试图联接包含备注或 OLE 对象数据的字段,将发生错误。  可以联接任何两个相似类型的数字字段。例如,可以联接自动编号和长整型字段,因为它们均是相似类型。然而,不能联接单精度型和双精度型类型字段。  下例展示了如何通过 CategoryID 字段联接 Categories 和 Products 表: SELECT CategoryName, ProductName FROM Categories INNER JOIN Products  ON Categories.CategoryID = Products.CategoryID;  在前面的示例中,CategoryID 是被联接字段,但是它不包含在查询输出中,因为它不包含在 SELECT 语句中。若要包含被联接字段,请在 SELECT 语句中包含该字段名,在本例中是指 Categories.CategoryID。  也可以在 JOIN 语句中链接多个 ON 子句,请使用如下语法: SELECT fields  FROM table1 INNER JOIN table2  ON table1.field1 compopr table2.field1 AND ON table1.field2 compopr table2.field2 OR ON table1.field3 compopr table2.field3; 也可以通过如下语法嵌套 JOIN 语句: SELECT fields  FROM table1 INNER JOIN (table2 INNER JOIN [( ]table3  [INNER JOIN [( ]tablex [INNER JOIN ...)] ON table3.field3 compopr tablex.fieldx)] ON table2.field2 compopr table3.field3) ON table1.field1 compopr table2.field2;  LEFT JOIN 或 RIGHT JOIN 可以嵌套在 INNER JOIN 之中,但是 INNER JOIN 不能嵌套于 LEFT JOIN 或 RIGHT JOIN 之中。   2.操作实例  表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并不以谁为基础,它只显示符合条件的记录. 还有就是inner join 可以结合where语句来使用 如: select * from A innerjoin B on A.aID = B.bID where b.bname='2006032401' 这样的话 就只会放回一条数据了

 

根据SQL语法,通过连接运算符可以实现多个表查询。连接可以在Select 语句的FROM子句或Where子句中建立,在FROM子句中指出连接时有助于将连接操作与Where子句中的搜索条件区分开来。    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)三种。与内连接不同的是,外连接不只列出与连接条件相匹配的行,而是列出左表(左外连接时)、右表(右外连接时)或两个表(全外连接时)中所有符合搜索条件的数据行。  前提:假设已存在外部数据库,并且已经打开包含a表、b表、c表三表的Mdb数据库。根据SQL语法规则,写出如下代码:  1. 内查询(查询三个表中均存在的ID记录,任何一个表中不存在的id将均被过滤掉)      .版本 2  记录集句柄 = 外部数据库1.查询 (“select * from a表 inner join b表 on a表.id=b表.id inner join c表 on a表.id=c表.id ” )'+ “ where „„”) ' where 条件暂时省略   2. 外查询(left join ,列出左表中的全部ID,不管b、c表中有无该ID) .版本 2  记录集句柄 = 外部数据库1.查询 (“select * from a表 left join b表 on a表.id=b表.id left join c表 on a表.id=c表.id ” )'+ “ where „„”) ' where 条件暂时省略   可是运行结果均为查询失败,如果仅仅两个表,查询则成功,三个或三个以上的表就会失败。  经过一天的捉摸,终于弄明白了问题原因,问题不在SQl,也不在易语言,而是没弄明白Access对SQL的支持,将上述代码改为如下代码,问题解决! .版本 2  记录集句柄 = 外部数据库1.查询 (“select * from (a表 inner join b表 on a表.id=b表.id) inner join c表 on a表.id=c表.id ”) ' + “ where „„”) ' where 条件暂时省略   .版本 2   2  记录集句柄 = 外部数据库1.查询 (“select * from (a表 left join b表 on a表.id=b表.id) left join c表 on a表.id=c表.id ”) ' + “ where „„”) ' where 条件暂时省略   如果有四张表,可以写为: .版本 2  记录集句柄 = 外部数据库1.查询 (“select * from ((a表 inner join b表 on a表.id=b表.id) inner join c表 on a表.id=c表.id) inner join d表 on a表.id=d表.id ”) ' + “ where „„”) ' where 条件暂时省略   问题很简单,想不到位则很头疼,为了众弟兄少走弯路,故尔拿出分享!是踩还是顶,随大家心意! 

 

 

SQL Server数据库多表关联汇总查询是我们经常用到的,本文我们就介绍了一个多表关联汇总查询的实例,通过这个实例在多表关联查询中遇到的问题以及它的解决方法让我们一起来了解一下SQL Server数据库多表关联汇总查询的相关知识吧……    SQL Server数据库多表关联汇总查询是我们经常用到的,本文我们就介绍了一个多表关联汇总查询的实例,通过这个实例在多表关联查询中遇到的问题以及它的解决方法让我们一起来了解一下SQL Server数据库多表关联汇总查询的相关知识吧,希望本次的介绍能够对您有所帮助。  以下是代码片段:   select isnull(s.mnumber,ss.mnumber) mnumber,isnull(m.whcode,ss.whcode) whcode,  isnull(sum(factreceiptquan),0)-isnull(sum(factissuequan),0) + sum(isnull(ss.quan,0)) quan  from (select * from gy_inoutmain where billcode in('1201','1202','1203','1204','1205','1206') ) m  inner join gy_inoutsub s on m.inoutmainid=s.inoutmainid  left join(   select sms.mnumber,sm.whcode,sum(sms.quan) quan from Kf_StartMain sm  inner join Kf_Startsub sms on sm.startmainid=sms.startmainid  group by sm.whcode,sms.mnumber   ) ss on m.whcode=ss.whcode and s.mnumber=ss.mnumber   group by isnull(m.whcode,ss.whcode),isnull(s.mnumber,ss.mnumber) order by s.mnumber     上面将收发表的数量进行汇总,然后再加上期初表的数量,得到库存量。但是得到的实际数量却多出很多来,比如本来物料“010101004”只有20吨,统计的结果却有5000多吨。问题出在哪里呢?  以下是代码片段:   select sms.mnumber,sm.whcode,sum(sms.quan) quan from Kf_StartMain sm  inner join Kf_Startsub sms on sm.startmainid=sms.startmainid  where sms.mnumber='010101004 '  group by sm.whcode,sms.mnumber     上面sql统计[期初表] 数量 = 31.500000  以下是代码片段:   select s.mnumber,m.whcode,   isnull(sum(factreceiptquan),0)-isnull(sum(factissuequan),0) quan   from (select * from gy_inoutmain where billcode in('1201','1202','1203','1204','1205','1206') ) m  inner join gy_inoutsub s on m.inoutmainid=s.inoutmainid  where s.mnumber='010101004 '  group by m.whcode,s.mnumber  order by s.mnumber     上面sql统计[收发表] 数量 = -27.000000  以下是代码片段:   select s.mnumber,m.whcode,   isnull(sum(factreceiptquan),0)-isnull(sum(factissuequan),0) +sum(ss.quan) quan   from (select * from gy_inoutmain where billcode in('1201','1202','1203','1204','1205','1206') ) m  inner join gy_inoutsub s on m.inoutmainid=s.inoutmainid  left join(   select sms.mnumber,sm.whcode,sum(sms.quan) quan from Kf_StartMain sm  inner join Kf_Startsub sms on sm.startmainid=sms.startmainid  where sms.mnumber='010101004 '  group by sm.whcode,sms.mnumber   ) ss on m.whcode=ss.whcode and s.mnumber=ss.mnumber  where s.mnumber='010101004 '  group by m.whcode,s.mnumber  order by s.mnumber    上面sql关联两表,数量=57145.500000,原来,在[收发表]关联[期初表],[收发表]有几百条记录,而[期初表]只有一条记录,两者一关联,则这几百条记录都有期初数,结果期初数被累加了几百次。   举个例子:  以下是代码片段:   create table [期初表](MNUmber varchar(10),quan decimal(10,3))  create table [收发表](MNUmber varchar(10),quan decimal(10,3))    insert into [期初表] values('001',7)  insert into [期初表] values('001',5)  insert into [期初表] values('001',-9)    insert into [收发表] values('001',10)    select sum(quan) from 期初表 --期初表合计=3    那得到的现存量应该是 [收发表]的合计 加上 期初数:3+10 = 13。但一关联,再汇总,就出问题了。  以下是代码片段:  select sum(m.Quan)+sum(s.Quan) from [收发表] m  inner join [期初表] s on m.MNumber=s.MNumber  group by m.MNumber     得到的结果是33。因为一关联,就变成:   以下是代码片段:   收发表.MNumber 收发表.quan 期初表.MNumber 期初表.quan  ---------------------------------------------------------------------  001 7 001 10  001 5 001 10  001 -9 001 10     结果就变成:7+5+(-9)+10+10+10,期初数被加了三次。解决的办法就是采用平级汇总的方式,先汇总,然后再关联。不要关联的两边,一边是明细,一边是汇总,那关联肯定出问题。

 

 

 

标签: net sql

WRITTEN BY

avatar