SQL技巧(三) - CTE实战之代替临时表

一段复杂的逻辑,原先的代码我使用#tmp临时表来实现,性能是不好的,而且要考虑到多用户时的锁的问题

代码如下:

declare  @StartDate  datetime
declare  @EndDate  datetime
select  @StartDate = ' 2012-09-28 '
select  @EndDate = ' 2012-10-03 '

if  exists ( select  *  from tempdb..sysobjects  where name  like  ' #tmpPolicyId% ')
     drop  table #tmpPolicyId
if  exists ( select  *  from tempdb..sysobjects  where name  like  ' #tmpSeasonFee% ')
     drop  table #tmpSeasonFee
if  exists ( select  *  from tempdb..sysobjects  where name  like  ' #tmpSpecialFee% ')
     drop  table #tmpSpecialFee
 
select PolicyId
into #tmpPolicyId
from GvInterPolicy
group  by PolicyId

select tmp.PolicyId,  max(AddFee)  as SeasonFee
into #tmpSeasonFee
from #tmpPolicyId tmp  inner  join GvSeasonFee season
     on tmp.PolicyId =season.PolicyId
where season.StartDate <= @StartDate  and season.EndDate >= @StartDate 
group  by tmp.PolicyId

select tmp.PolicyId,  max(AddFee)  as SpecialFee
into #tmpSpecialFee
from #tmpPolicyId tmp  inner  join GvSpecialFee special
     on tmp.PolicyId =special.PolicyId
where special.SpecialDate = @StartDate
group  by tmp.PolicyId


select p.PolicyId, p.AirComCode, p.DepStartTime, p.DepEndTime, p.SellStartTime, p.SellEndTime,
        p.StartCityCode, p.EndCityCode, r.FlightNo, r.SCityCode, r.ECityCode, r.STime, r.ETime,
        r.TerminalBuilding, r.RouteOrder, r.SCityName, r.ECityName, r.PlaneModel, r.IsBack,
        c.FirstCabin, c.SecondCabin, c.Price  as AdultPrice, 
         isnull(season.SeasonFee,  0as SeaFee,  isnull(special.SpecialFee,  0as SpFee,
        AddPrice = case  when  isnull(season.SeasonFee,  0) >= isnull(special.SpecialFee,  0then  isnull(season.SeasonFee,  0else  isnull(special.SpecialFee,  0end
from GvInterPolicy p  inner  join GvRouteInfo r
     on p.PolicyId =r.PolicyId  inner  join GvCabinInfo c
     on p.PolicyId =c.PolicyId  left  join #tmpSeasonFee season
     on p.PolicyId =season.PolicyId  left  join #tmpSpecialFee special
     on p.PolicyId =special.PolicyId 
where p.DepStartTime <= @StartDate  and p.DepEndTime >= @EndDate
order  by p.PolicyId, c.FirstCabin, c.SecondCabin, r.RouteOrder

 

使用CTE改进后的代码:

declare  @StartDate  datetime
declare  @EndDate  datetime
select  @StartDate = ' 2012-09-28 '
select  @EndDate = ' 2012-10-03 ';

with ctePolicyId(PolicyId)
as
(
     select PolicyId
     from GvInterPolicy
     group  by PolicyId
),
cteSeasonFee
as
(
     select p.PolicyId,  max(AddFee)  as SeasonFee
     from ctePolicyId p  inner  join GvSeasonFee season
         on p.PolicyId =season.PolicyId
     where season.StartDate <= @StartDate  and season.EndDate >= @StartDate 
     group  by p.PolicyId
),
cteSpecialFee
as
(
     select p.PolicyId,  max(AddFee)  as SpecialFee
     from ctePolicyId p  inner  join GvSpecialFee special
         on p.PolicyId =special.PolicyId
     where special.SpecialDate = @StartDate
     group  by p.PolicyId

)

select p.PolicyId, p.AirComCode, p.DepStartTime, p.DepEndTime, p.SellStartTime, p.SellEndTime,
        p.StartCityCode, p.EndCityCode, r.FlightNo, r.SCityCode, r.ECityCode, r.STime, r.ETime,
        r.TerminalBuilding, r.RouteOrder, r.SCityName, r.ECityName, r.PlaneModel, r.IsBack,
        c.FirstCabin, c.SecondCabin, c.Price  as AdultPrice, 
         isnull(season.SeasonFee,  0as SeaFee,  isnull(special.SpecialFee,  0as SpFee,
        AddPrice = case  when  isnull(season.SeasonFee,  0) >= isnull(special.SpecialFee,  0then  isnull(season.SeasonFee,  0else  isnull(special.SpecialFee,  0end
from GvInterPolicy p  inner  join GvRouteInfo r
     on p.PolicyId =r.PolicyId  inner  join GvCabinInfo c
     on p.PolicyId =c.PolicyId  left  join cteSeasonFee season
     on p.PolicyId =season.PolicyId  left  join cteSpecialFee special
     on p.PolicyId =special.PolicyId 
where p.DepStartTime <= @StartDate  and p.DepEndTime >= @EndDate
order  by p.PolicyId, c.FirstCabin, c.SecondCabin, r.RouteOrder

 

 

你可能感兴趣的:(sql)