2017-06-05 8 views
1
CREATE PROCEDURE [dbo].[CalendarMonthly] 
(
    @FROMDATE VARCHAR(25) 
) 
AS 
BEGIN 
SET NOCOUNT ON 

DECLARE @ADate DATETIME 
DECLARE @MonthCount INT 

SET @ADate = @FROMDATE 
SET @MonthCount = (SELECT DAY(EOMONTH(@ADate))) 

DECLARE @tmpTable TABLE 
    (  
    TRoomID INT, DAY1 INT, DAY2 INT,  DAY3 INT, DAY4 INT,   DAY5 INT, DAY6 INT,  DAY7 INT  
    ) 

    INSERT INTO @tmpTable 

    SELECT RM.ROOMID,  
      0,0,0,0,0,0,0 

     FROM RoomMaster AS RM 
     LEFT JOIN RoomTypes AS RT ON RM.RoomTypeID = RT.RoomTypeID 
      WHERE RM.RoomMasterStatus <> 99 

DECLARE @RoomID INT 
DECLARE @ForDate DATE 
DECLARE @dtFromDate DATE 
DECLARE @dtToDate DATE 

SET @dtFromDate = CONVERT(DATE,@FromDate) 
SET @ForDate = @dtFromDate 
SET @dtToDate = CONVERT(DATE,CONVERT(VARCHAR,YEAR(@dtFromDate)) +'-'+ CONVERT(VARCHAR,MONTH(DATEADD(M,1,@dtFromDate)))+'-1') 
SET @dtToDate = DATEADD(D,-1,@dtToDate) 

DECLARE @DayCount INT 

WHILE @ForDate <= @dtToDate 
    BEGIN 

     SET @DayCount = DAY(@ForDate) 

     IF @DayCount = 1 
      BEGIN 
        -- Checkin 
        UPDATE @tmpTable SET DAY1 = 1 

        FROM @tmpTable TT 
        JOIN RoomCheckinDetails AS RCD ON RCD.RoomID = TT.TRoomID 
        JOIN RoomCheckinMaster AS RCM ON RCM.CheckinID = RCD.CheckinID 
         WHERE CONVERT(DATE,RCD.CheckinDate) = @ForDate 
           AND RCD.RoomID = TT.TRoomID 

        -- Expected Checkin 
        UPDATE @tmpTable SET DAY1 = 8 

        FROM @tmpTable TT 
        JOIN RoomBookingDetails AS RBD ON RBD.RoomID = TT.TRoomID 
        JOIN RoomBookingMaster AS RBM ON RBM.ReservationID = RBD.ReservationID 
         WHERE CONVERT(DATE,RBD.ExpectedCheckinDate) = @ForDate 
           AND RBD.RoomID = TT.TRoomID    

      END 
      ELSE IF @DayCount = 2 
      . 
      . 
      . 
      . 
      . 
      . 
      ---upto Day count 7 


     SET @ForDate = DATEADD(Day,1,@ForDate) 

    END 


    SELECT * FROM @tmpTable 


END 

私の質問は:動的更新は

例:checkindate = 2017年4月6日、checoutdate =比較する2つの日付で2017年9月6日、私はアップデートを持っています1日1列から6列までの数値は0です。

+4

ご入力データセットとあなたの予想出力データセットとは何ですか?主にこれを行うためにループを必要としない場合があります –

+0

あなたの質問を書き直すのに役立つネイティブの英語スピーカーがありますか?私はあなたが何を求めようとしているのか分かりません。 –

答えて

0

一時テーブルを作成し、カーソルを使用して各列のセットを更新するのではなく、これをすべて回避するセットベースのソリューションです。最初の部分については

、あなただけの、あなたがcommon table expressionTable Value Constructor (Transact-SQL)で単純な値の集計テーブルを使用することができます7日必要がある場合:

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でのCTE:

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 joinroommasterと日付、および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()を(1を選択)を使用することができます:


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

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 | 
+--------+------+------+------+------+------+------+------+ 

番号とカレンダー表参照: