使用两个日期之间的不同列的动态更新,如日历日期

时间:2017-06-05 10:26:57

标签: sql-server

Test(MyTest, InnerATest)
{
    TestA::InnerA x;
    x.DoSth();
}

我的问题是:

例如:checkindate = 04/06/2017,checoutdate = 9/06/2017比较两个日期我更新到第day1列到第6天的值第6个值为0.

1 个答案:

答案 0 :(得分:0)

这是一个基于集合的解决方案,可以避免所有这些,而不是创建临时表并使用游标来更新每组列。

对于第一部分,如果您只需要7天,那么您可以使用包含common table expressionTable Value Constructor (Transact-SQL)的简单值统计表:

declare @fromdate date = '20170605';
;with dates as (
  select 
      [Date]=convert(date,dateadd(day,rn-1,@fromdate))
    , rn 
  from (values (1),(2),(3),(4),(5),(6),(7)) t(rn)
)

否则,您可以使用common table expression中的堆叠ctes生成一个日期临时表,如下所示:

declare @fromdate date = '20170605';
declare @thrudate date = dateadd(day,6,@fromdate)

;with n as (select n from (values(0),(1),(2),(3),(4),(5),(6),(7),(8),(9)) t(n))
, dates as (
  select top (datediff(day, @fromdate, @thrudate)+1) 
      [Date]=convert(date,dateadd(day,row_number() over(order by (select 1))-1,@fromdate))
    , rn = row_number() over(order by (select 1))
  from n as deka cross join n as hecto cross join n as kilo
                 cross join n as tenK cross join n as hundredK
   order by [Date]
)

然后cross join roommaster的日期和left join的签到和预订表,以查看房间是否有预订或当前是否已被占用:

, cte as (
select 
    rm.roomid
  , d.rn
  , Value = case 
      when rcd.roomid is not null then 1
      when rbd.roomid is not null then 8
      else 0
      end
from dates d
  cross join roommaster rm
  left join roomcheckindetails rcd
    on rm.roomid = rcd.roomid 
   and d.date >= rcd.checkindate 
   and d.date <= rcd.checkoutdate
  left join roombookingdetails rbd
    on rm.roomid = rbd.roomid
   and d.date >= rbd.expectedcheckindate 
   and d.date <= rbd.expectedcheckoutdate
where rm.roommasterstatus <> 99
)

然后对于最后一部分,您可以使用条件聚合或pivot()(选择一个),如下所示:

select 
    roomid
  , Day1 = min(case when rn = 1 then value end)
  , Day2 = min(case when rn = 2 then value end)
  , Day3 = min(case when rn = 3 then value end)
  , Day4 = min(case when rn = 4 then value end)
  , Day5 = min(case when rn = 5 then value end)
  , Day6 = min(case when rn = 6 then value end)
  , Day7 = min(case when rn = 7 then value end)
from cte
group by roomid
select 
    roomid
  , Day1 = [1]
  , Day2 = [2]
  , Day3 = [3]
  , Day4 = [4]
  , Day5 = [5]
  , Day6 = [6]
  , Day7 = [7]
from cte
  pivot (min(value) for rn in ([1],[2],[3],[4],[5],[6],[7]))p

带有条件聚合的rextester演示:http://rextester.com/RUJ98491

带有pivot()的rextester演示:http://rextester.com/YNKU89188

对我的演示数据都返回相同的结果:

+--------+------+------+------+------+------+------+------+
| roomid | Day1 | Day2 | Day3 | Day4 | Day5 | Day6 | Day7 |
+--------+------+------+------+------+------+------+------+
|      2 |    1 |    1 |    1 |    1 |    0 |    0 |    0 |
|      3 |    0 |    8 |    8 |    8 |    8 |    0 |    0 |
+--------+------+------+------+------+------+------+------+

数字和日历表参考: