|
Posted on 2006-08-15 18:23 大大毛 閱讀(210) 評(píng)論(0) 編輯 收藏 所屬分類(lèi): SQL
???問(wèn)題(示例): ??????投票表vote,根據(jù)條件查詢(xún) 有效/失效/全部 的投票主題,是否有效的條件是將當(dāng)前日期與投票的有效期進(jìn)行比較
 vote表結(jié)構(gòu) create?table?vote?( ??--投票ID,主鍵 ??vID?int?identity(1,1)?primary?key, ??--投票主題 ??topic?varchar(50)?not?null, ??--生效日期 ??beginDate?datetime?default(getdate()), ??--失效日期 ??endDate?datetime?default(getdate()) ) ??????示例數(shù)據(jù):
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())?) ??????實(shí)現(xiàn)效果 ?????????有效投票為 topic01?,無(wú)效投票為 topic02
???解決方法:
 自連接查詢(xún)1 --獲取全部投票 --auther:ddm --last:2006-8-15 --參數(shù) --??isValid(int):缺省值為全部投票 --????0:無(wú)效投票 --????1:有效投票 --????other:全部投票 create?procedure?vote_GetAllVote ??--包含的投票類(lèi)型:0,無(wú)效投票;1,有效投票;other,全部投票 ??@isValid?int?=?null as begin ??--獲取服務(wù)器當(dāng)前日期 ??declare?@now?datetime ??set?@now?=?getdate() ??-- ??if?@isValid?!=0?and?@isvalid?!=1 ??begin ????set?@isValid?=?null ??end
??select ??????vote.* ????from ??????( ????????--篩選當(dāng)前有效的投票 ????????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 ???在使用自連接查詢(xún)時(shí),使用判斷條件生成一個(gè)臨時(shí)的子表進(jìn)行自連接。利用左/右連接時(shí)子表對(duì)應(yīng)列為 null 的轉(zhuǎn)換從而達(dá)到在 vote 表中插入一個(gè)特征列的目的,忽略掉最后的 where 子句,手工在 select vote.* 處加入? ,isValid即可以看到效果。
???可以將SQL語(yǔ)句改寫(xiě)成下面這樣,可以看得清楚一些。
 自連接查詢(xún)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) ???也可以根據(jù)需要,改寫(xiě)成子查詢(xún)語(yǔ)句:
 子查詢(xún) 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 參數(shù),即可演示效果(sqlServer2000) ???當(dāng)然,生成兩個(gè)臨時(shí)表 validVote,invalidVote再聯(lián)合查詢(xún)?或者 用IF 加開(kāi)關(guān)分開(kāi)select也是可以的,這里就不贅述了。
???后記: ??????SQL語(yǔ)法上并沒(méi)有規(guī)定解決問(wèn)題只能使用一種方案,它采用了非常靈活的工作方式,因此具體使用哪一種解決方案取決于具體的應(yīng)用及個(gè)人喜好。
|