3

以下の SQL クエリは、教師の空き状況を表示することになっています。可能な予約タイプは、午前、午後、終日、時間単位の 4 つです。午前の予約がある場合、セル内のテキストは PM と表示され、午後の予約がある場合は AM と表示され、終日予約の場合、または午前と午後の両方の予約がある場合は「xxx」と表示されます。時間単位の予約 - 午前 (開始時刻 <= 午後 12 時) に 1 つ、午後 (終了時刻 > 午後 12 時) に 1 つずつ、毎日 2 つの時間単位の予約しかないと想定しても問題ありません。つまり、「xxx」と表示する必要があります。 '。これはすべてうまくいきます。

問題は、午前の予約の後に午後の時間単位の予約がある場合、または午前の時間単位の予約で午後の予約がある場合に「XXX」を表示することです。

    WITH Bookings AS
    (  SELECT  TeacherID,
            [WeekDay] = DATENAME(WEEKDAY, BookingDate),
            [0], [1], [2], [3],
            [Status] = CASE 
                        WHEN ([0] > 0 AND [1] > 0) THEN 'XXX'
                        WHEN [2] > 0 THEN 'XXX'  
                        WHEN [0] > 0 THEN 'PM'
                        WHEN [1] > 0 THEN 'AM'  
                        WHEN [3] > 0 AND StartTime <= CONVERT(TIME, '12:00:00') AND EndTime >= CONVERT(TIME, '12:00:00') THEN 'XXX'   
                        WHEN [3] > 0 AND EndTime <= CONVERT(TIME, '12:00:00') THEN 'PM'
                        WHEN [3] > 0 AND StartTime >= CONVERT(TIME, '12:00:00') THEN 'AM'  

                        END
    FROM    (   SELECT  TeacherID, 
                        BookingDate, 
                        BookingDuration, 
                        StartTime = CASE WHEN BookingDuration = 3 THEN CAST(MIN(StartTime) OVER(PARTITION BY TeacherID, BookingDate, BookingDuration) AS TIME) ELSE NULL END,
                        EndTime = CASE WHEN BookingDuration = 3 THEN CAST(MAX(EndTime) OVER(PARTITION BY TeacherID, BookingDate, BookingDuration) AS TIME) ELSE NULL END,                        
                        [x] = 1
                FROM    BookingDays 
                WHERE   (Status = 0 OR Status IS NULL)
            ) BookingDays
            PIVOT
            (   SUM(x)
                FOR BookingDuration IN ([0], [1], [2], [3])
            ) pvt

             WHERE BookingDate >= DATEADD(ww, DATEDIFF(ww,0,'05/06/2013'), 0) AND BookingDate <= DATEADD(ww, DATEDIFF(ww,0,'05/06/2013'), 6)

    ), PivotedBookings AS
    (   SELECT  *
    FROM    Bookings
            PIVOT
            (   MAX([Status])
                FOR [WeekDay] IN ([Monday], [Tuesday], [Wednesday], [Thursday], [Friday])
            ) pvt

    )
    SELECT ID,Firstname,Surname,Band,'£' + CONVERT(varchar(50),DefaultChargeRateDaily) + '/' + '£' + CONVERT(varchar(50), DefaultPayRateDaily) as 'BandRates',Telephone,Mobile,Teacher,TeacherAssistant,KeyStage,MAX(Monday) Monday,MAX(Tuesday) Tuesday,MAX(Wednesday) Wednesday,MAX(Thursday) Thursday,MAX(Friday) Friday, Notes
      FROM (
SELECT  t.ID, 
        t.Firstname, 
        t.Surname, 
        tb.Band,
        t.DefaultChargeRateDaily,
        t.DefaultPayRateDaily,
        t.Telephone,
        t.Mobile,
        t.Teacher,
        t.TeacherAssistant,
        CASE WHEN t.Nursery > 0 THEN 'NUR' WHEN t.Reception > 0 THEN 'REC' WHEN t.Year1 > 0 THEN 'Y1' WHEN t.Year2 > 0 THEN 'Y2' WHEN t.Year3 > 0 THEN 'Y3' WHEN t.Year4 > 0 THEN 'Y4' WHEN t.Year5 > 0 THEN 'Y5' WHEN t.Year6 > 0 THEN 'Y6' WHEN t.Year7 > 0 THEN 'Y7' WHEN t.Year8 > 0 THEN 'Y8' WHEN t.Year9 > 0 THEN 'Y9' WHEN t.Year10 > 0 THEN 'Y10' WHEN t.Year11 > 0 THEN 'Y11' WHEN t.ALevel > 0 THEN 'ALevel' END + ' - ' + CASE WHEN t.ALevel > 0 THEN 'ALevel' WHEN t.Year11 > 0 THEN 'Y11' WHEN t.Year10 > 0 THEN 'Y10' WHEN t.Year9 > 0 THEN 'Y9' WHEN t.Year8 > 0 THEN 'Y8' WHEN t.Year7 > 0 THEN 'Y7' WHEN t.Year6 > 0 THEN 'Y6' WHEN t.Year5 > 0 THEN 'Y5' WHEN t.Year4 > 0 THEN 'Y4' WHEN t.Year3 > 0 THEN 'Y3' WHEN t.Year2 > 0 THEN 'Y2' WHEN t.Year1 > 0 THEN 'Y1' WHEN t.Reception > 0 THEN 'REC' WHEN t.Nursery > 0 THEN 'NUR' ELSE '' END as 'KeyStage',

        Monday = CASE WHEN an.Date = DATEADD(ww, DATEDIFF(ww,0,'05/06/2013'), 0) AND an.TeacherID = t.ID THEN an.Text WHEN t.Status = 0 THEN 'XXX'  ELSE COALESCE(pb.Monday, '') END,
        Tuesday = CASE WHEN an.Date = DATEADD(ww, DATEDIFF(ww,0,'05/06/2013'), 1) AND an.TeacherID = t.ID THEN an.Text WHEN t.Status = 0 THEN 'XXX'  ELSE COALESCE(pb.Tuesday, '') END,
        Wednesday = CASE WHEN an.Date = DATEADD(ww, DATEDIFF(ww,0,'05/06/2013'), 2) AND an.TeacherID = t.ID THEN an.Text WHEN t.Status = 0 THEN 'XXX'  ELSE COALESCE(pb.Wednesday, '') END,
        Thursday = CASE WHEN an.Date = DATEADD(ww, DATEDIFF(ww,0,'05/06/2013'), 3) AND an.TeacherID = t.ID THEN an.Text WHEN t.Status = 0 THEN 'XXX'  ELSE COALESCE(pb.Thursday, '') END,
        Friday = CASE WHEN an.Date = DATEADD(ww, DATEDIFF(ww,0,'05/06/2013'), 4) AND an.TeacherID = t.ID THEN an.Text WHEN t.Status = 0 THEN 'XXX'  ELSE COALESCE(pb.Friday, '') END,
        Notes
FROM    Teachers t

        LEFT JOIN PivotedBookings pb
            ON pb.TeacherID = t.ID
        LEFT JOIN TeacherBands tb
            ON tb.ID = t.Band
        LEFT JOIN AvailabilityNotes an 
            ON t.ID = an.TeacherID
            WHERE t.Active = 0 and (t.Status = 1 or t.Status = 0) and t.PrimarySchool = 1 and t.ID = 9094
            ) T1
 GROUP BY ID,Firstname,Surname,Telephone,Mobile,Teacher,TeacherAssistant,KeyStage,Notes,DefaultChargeRateDaily,DefaultPayRateDaily,Band
 ORDER BY Surname,Firstname asc

最初の部分は以下を生成します -

SELECT  TeacherID,
            [WeekDay] = DATENAME(WEEKDAY, BookingDate),
            [0], [1], [2], [3],
            [Status] = CASE 
                            WHEN ([0] > 0 AND [1] > 0) THEN 'XXX'
                            WHEN [2] > 0 THEN 'XXX'  
                            WHEN [0] > 0 THEN 'PM'
                            WHEN [1] > 0 THEN 'AM'  
                            WHEN ([3] > 0 AND EndTime <= CONVERT(TIME, '12:00:00')) AND ([0] > 1) THEN 'XXX'
                            WHEN ([3] > 0 AND EndTime <= CONVERT(TIME, '12:00:00')) AND ([1] > 1) THEN 'XXX'
                            WHEN [3] > 0 AND StartTime <= CONVERT(TIME, '12:00:00') AND EndTime >= CONVERT(TIME, '12:00:00') THEN 'XXX'   
                            WHEN [3] > 0 AND EndTime <= CONVERT(TIME, '12:00:00') THEN 'PM'
                            WHEN [3] > 0 AND StartTime >= CONVERT(TIME, '12:00:00') THEN 'AM'                     

                        END
    FROM    (   SELECT  TeacherID, 
                        BookingDate, 
                        BookingDuration, 
                        StartTime = CASE WHEN BookingDuration = 3 THEN CAST(MIN(StartTime) OVER(PARTITION BY TeacherID, BookingDate, BookingDuration) AS TIME) ELSE NULL END,
                        EndTime = CASE WHEN BookingDuration = 3 THEN CAST(MAX(EndTime) OVER(PARTITION BY TeacherID, BookingDate, BookingDuration) AS TIME) ELSE NULL END,                        
                        [x] = 1
                FROM    BookingDays 
                WHERE   (Status = 0 OR Status IS NULL)
            ) BookingDays
            PIVOT
            (   SUM(x)
                FOR BookingDuration IN ([0], [1], [2], [3])
            ) pvt

             WHERE BookingDate >= DATEADD(ww, DATEDIFF(ww,0,'05/06/2013'), 0) AND BookingDate <= DATEADD(ww, DATEDIFF(ww,0,'05/06/2013'), 6)

.

TeacherID | WeekDay  | 0     | 1     | 2     | 3     | Status
9094      | Monday   | NULL  | NULL  | 1     | NULL  | XXX
9094      | Tuesday  | NULL  | NULL  | NULL  | 1     | AM
9094      | Wednesday| NULL  | 1     | NULL  | NULL  | AM
9094      | Thursday | NULL  | 1     | NULL  | NULL  | AM
9094      | Thursday | NULL  | NULL  | NULL  | 1     | PM
9094      | Friday   | NULL  | NULL  | 1     | 1     | XXX

予約期間 -

0 - 午前 1 - 午後 2 - 終日 3 - 毎時

ここでわかるように、木曜日の 2 つの行は、2 つの別々の行ではなく、マージしてステータス列に XXX として表示する必要があります。

以下のスクリーンショットに例を示します。黄色で強調表示され、PM を示していますが、1 時間ごとに午後 1 時と午前があるため、XXX を表示する必要があります。

必要なもののスクリーンショット

毎時と午前、または毎時と午後があるときに XXX を表示するにはどうすればよいですか?

ありがとう!

4

1 に答える 1

2

複雑なロジックを 2 つのステップに分割し、IntermediateBookings CTE を使用してロジックを 2 つの列has_amhas_pm. これらは計算がより簡単で、これらから最終的な出力も簡単に計算できます。理論的には、元のステートメントの表現を改善して、さらにs とsCASEを含めることはできますが、これはあまり維持できません。クエリの開始は次のようになります。ANDOR

WITH IntermediateBooking as (
SELECT  TeacherID,
            [WeekDay] = DATENAME(WEEKDAY, BookingDate),
            [0], [1], [2], [3],
            has_am = case when 
                          [1] > 0
                       OR [2] > 0
                       OR ([3] > 0 AND StartTime <= CONVERT(TIME, '12:00:00'))
                     then 1
                     else null
                     end,
            has_pm = case when 
                          [0] > 0
                       OR [2] > 0
                      OR ([3] > 0 AND EndTime >= CONVERT(TIME, '12:00:00'))
                     then 1
                     else null
                     end
    FROM    (   SELECT  TeacherID, 
                        BookingDate, 
                        BookingDuration, 
                        StartTime = CASE WHEN BookingDuration = 3 THEN CAST(MIN(StartTime) OVER(PARTITION BY TeacherID, BookingDate, BookingDuration) AS TIME) ELSE NULL END,
                        EndTime = CASE WHEN BookingDuration = 3 THEN CAST(MAX(EndTime) OVER(PARTITION BY TeacherID, BookingDate, BookingDuration) AS TIME) ELSE NULL END,                        
                        [x] = 1
                FROM    BookingDays 
                WHERE   (Status = 0 OR Status IS NULL)
            ) BookingDays
            PIVOT
            (   SUM(x)
                FOR BookingDuration IN ([0], [1], [2], [3])
            ) pvt

             WHERE BookingDate >= DATEADD(ww, DATEDIFF(ww,0,'05/06/2013'), 0) AND BookingDate <= DATEADD(ww, DATEDIFF(ww,0,'05/06/2013'), 6)
),
Bookings AS (
SELECT TeacherID, [WeekDay],
       case when sum(has_am) > 0 and sum(has_pm) > 0 then 'XXX'
            WHEN sum(has_am) > 0 then 'AM'
            WHEN sum(has_pm) > 0 then 'PM'
       end as [Status]
  FROM IntermediateBookings
GROUP BY TeacherID, [WeekDay]
)

残りは - から始めてPivotedBookings- あなたが持っているままにすることができます.

ただし、使用可能なテーブルがないため、構文エラーや、結果が要求どおりかどうかを確認できません。微調整が必​​要な場合があります。

于 2013-08-30T18:27:53.187 に答える