|
Posted on 2006-08-15 18:23 大大毛 阅读(199) 评论(0) 编辑 收藏 所属分类: SQL
问题(示例): 投票表vote,根据条件查询 有效/失效/全部 的投票主题,是否有效的条件是将当前日期与投票的有效期进行比较
vote表结构 create table vote ( --投票ID,主键 vID int identity(1,1) primary key, --投票主题 topic varchar(50) not null, --生效日期 beginDate datetime default(getdate()), --失效日期 endDate datetime default(getdate()) ) 示例数据:
insert into vote values ( 'topic01',dateadd(day,-2,getdate()),dateadd(day,2,getdate()) ) insert into vote values ( 'topic02',dateadd(day,-20,getdate()),dateadd(day,-10,getdate()) ) 实现效果 有效投票为 topic01 ,无效投票为 topic02
解决方法:
自连接查询1 --获取全部投票 --auther:ddm --last:2006-8-15 --参数 -- isValid(int):缺省值为全部投票 -- 0:无效投票 -- 1:有效投票 -- other:全部投票 create procedure vote_GetAllVote --包含的投票类型:0,无效投票;1,有效投票;other,全部投票 @isValid int = null as begin --获取服务器当前日期 declare @now datetime set @now = getdate() -- if @isValid !=0 and @isvalid !=1 begin set @isValid = null end
select vote.* from ( --筛选当前有效的投票 select vID, isValid = 1 from vote where @now between beginDate and endDate ) validVote right join vote on validVote.vID = vote.vID where isNull(isValid,0) = isNull(@isValid,isNull(isValid,0)) end 在使用自连接查询时,使用判断条件生成一个临时的子表进行自连接。利用左/右连接时子表对应列为 null 的转换从而达到在 vote 表中插入一个特征列的目的,忽略掉最后的 where 子句,手工在 select vote.* 处加入 ,isValid即可以看到效果。
可以将SQL语句改写成下面这样,可以看得清楚一些。
自连接查询2 select vID, topic from ( select vote.*, isValid = isNull(isValid,0) from ( select vID, isValid = 1 from vote where @now between beginDate and endDate ) validVote right join vote on validVote.vID = vote.vID ) newVote where isValid = isNull(@isValid,isValid) 也可以根据需要,改写成子查询语句:
子查询 select vID, topic from ( select *, isValid = isnull( (select 1 from vote sub where sub.vid=vote.vid and @now between beginDate and endDate ) ,0) from vote ) newVote where isValid = isNull(@isValid,isValid) 使用 exec vote_getAllVote 参数,即可演示效果(sqlServer2000) 当然,生成两个临时表 validVote,invalidVote再联合查询 或者 用IF 加开关分开select也是可以的,这里就不赘述了。
后记: SQL语法上并没有规定解决问题只能使用一种方案,它采用了非常灵活的工作方式,因此具体使用哪一种解决方案取决于具体的应用及个人喜好。
|