|
Posted on 2006-08-15 18:23 大大毛 閱讀(210) 評論(0) 編輯 收藏 所屬分類: SQL
???問題(示例): ??????投票表vote,根據(jù)條件查詢 有效/失效/全部 的投票主題,是否有效的條件是將當(dāng)前日期與投票的有效期進行比較
 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())?) ??????實現(xiàn)效果 ?????????有效投票為 topic01?,無效投票為 topic02
???解決方法:
 自連接查詢1 --獲取全部投票 --auther:ddm --last:2006-8-15 --參數(shù) --??isValid(int):缺省值為全部投票 --????0:無效投票 --????1:有效投票 --????other:全部投票 create?procedure?vote_GetAllVote ??--包含的投票類型:0,無效投票;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 ???在使用自連接查詢時,使用判斷條件生成一個臨時的子表進行自連接。利用左/右連接時子表對應(yīng)列為 null 的轉(zhuǎn)換從而達到在 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) ???也可以根據(jù)需要,改寫成子查詢語句:
 子查詢 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)然,生成兩個臨時表 validVote,invalidVote再聯(lián)合查詢?或者 用IF 加開關(guān)分開select也是可以的,這里就不贅述了。
???后記: ??????SQL語法上并沒有規(guī)定解決問題只能使用一種方案,它采用了非常靈活的工作方式,因此具體使用哪一種解決方案取決于具體的應(yīng)用及個人喜好。
|