RickTroy

Richard Troy-Rex's Microsoft .NET Technology Blog 博客内所有文章和随笔均为个人言论,本着交流、共享的宗旨,允许转载,但请在转载的时候注明出处。如果对文章、随笔的内容有任何指正和异议,请电子邮件联系ricktroy@126.com。

无中间表数据的表连接

作者:Ricktroy (ricktroy@126.com, http://ricktroy.cnblogs.com/ )

问题:表A为部门表,表B为员工表,数据库中存在表C为部门-员工对应关系表(为了阐述问题所以使用部门、员工两种数据实体,实际在设计的情况下可以把这个关系设计在员工表中。项目中遇到的是两种关系特殊,即业务逻辑连接比较脆弱的两个数据实例,这里只是拿部门、员工两种数据实例来举个例子)。
         因为是Web应用程序,表C的数据早已经从数据库中取出放在了会话变量中,在经过了长时间的业务操作后,要通过存储在会话变量中的表C中的一条数据检索出表A的一条数据和表B的0~n条数据的组合,要求表B数据为0条的时候,检出数据一条为表B的一条数据。

以上就是我昨天所遇到的一个业务问题,为了减少数据库访问,虽然是两个逻辑关系十分脆弱(脆弱的原因是联系两张表数据的数据不在数据库中,而是在应用程序侧),最后的解决方案是,用会话变量中的数据作为限定条件(Where子句),检出的两张子表用左外连接。左外连接的使用根据问题的最后一条就可以想到,但是两张表却没有明确的连接关系,实际上因为会话变量作为检索条件的原因,两张表检出的数据一定是符合业务要求的,那么我们需要做的就是进行“硬性连接”方法如下:

Select A.*,B.* From (Select *, 1 as Conn From Table1 Where Table1.Var1=[SessionVariable1]) A Left Outer Join
(Select *, 1 as Conn From Table2 Where Table2.Var2=[SessionVariable2]) B On A.Conn = B.Conn
OrderBy A.SortOrd1 ASC,B.SortOrder DESC

黑体的内容就是“硬性连接“的方法。SessionVariable1、SessionVariable2 是联系两张表的会话变量。最后排序的时候要注意OrderBy不能出现于子查询中要写在最外面。

posted on 2007-01-09 07:56 RickTroy 阅读(2038) 评论(8) 编辑 收藏

评论

#1楼 2007-01-09 08:53 charleschen      

呵呵,楼主好文。
我看了之后想到一个写法,不知道适不适合你的业务

Select A.*,B.*
From (Select * From Table1 Where Table1.Var1=[SessionVariable1]) A
Left Outer Join
(Select *, From Table2 Where Table2.Var2=[SessionVariable2]) B On 1=1
OrderBy A.SortOrd1 ASC,B.SortOrder DESC
 回复 引用 查看   

#2楼 2007-01-09 12:53 Ricktroy[匿名][未注册用户]

@charleschen
这个想法我也试过,但是运行结果是变成了全连接,因为在SQL中On后是连接条件,SQL内核通过条件中对等关系的列名去做连接,如果没有对应的条件就会变成全连接,所以1=1对于左外连接没有意义。如果有错误请指正,谢谢对我博客的关注。
Ricktroy
 回复 引用   

#3楼 2007-01-09 21:34 lee[匿名][未注册用户]

请问这是在sqlserver 2005里执行的sql语句么?
SessionVariable1 是从哪来的?
1 as Conn 是什么?
谢谢!
 回复 引用   

#4楼 2007-01-10 08:05 Ricktroy[匿名][未注册用户]

这是符合SQL99标准的SQL语句,在各种支持SQL99的数据库上都可以使用:包括SQL Server 2000和SQL Server 2005。
对于SessionVariable1、SessionVariable2 是联系两张表的会话变量。可能是我忘记说清楚开发环境的原因,我们开发的是Web应用程序,使用的中间数据都存在会话(Session)变量中。
1 As Conn就是在映射出的子表中硬性地创建数据一致的列作为连接条件,是一种“强制性设置”。
 回复 引用   

#5楼 2007-01-10 16:18 Pizza[未注册用户]

1=1不行吗? 没注意....
Select * From
Table1 A LEFT Outer Join
(
SELECT * FROM Table2
WHERE Table2.Var2=[SessionVariable2]
)B
ON 1=1
WHERE Table1.Var1=[SessionVariable1]
 回复 引用   

#6楼 2007-01-11 08:23 Ricktroy[匿名][未注册用户]

今天试了一下你的,可以使用,但是我那天去处理那个问题的时候用1=1做连接可以使用。但是那天用的时候居然出现了全连接,修改成Conn=1的这种形式就可以使用了,因为详细关系没有追查原因。我会再去看一下。谢谢你的提醒。  回复 引用   

#7楼 2007-01-11 11:37 Pizza[未注册用户]

修改成Conn=1 跟1=1 其实没有区别,A跟B中的Conn全部都是1,A.Conn=B.Conn其结果还是1=1, 对吧.:)  回复 引用   

#8楼 2007-01-11 11:57 Ricktroy[匿名][未注册用户]

应该是这样,但是不知道上次是我看错还是还有什么需要注意的地方,现在因为工作很忙就不再查了。感谢Pizza的指正,以后还要多来做客。  回复 引用