2013-08-28 40 views
3

下面的SQL查詢應該顯示教師可用性。有4種可能的預訂類型 - 上午,下午,全天和每小時。如果有AM預訂,單元格中的文本應該顯示PM,如果有PM預定,它應該顯示AM,如果有整天預訂,或AM和PM預訂,它應該顯示'xxx'。每小時預訂 - 可以肯定的是,每天只有2小時預訂,AM爲1(開始時間< = 12pm),PM爲1(結束時間> 12pm),這意味着我們應該顯示'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 - AM 1 - PM 2 - 全天 3 - 每小時

我們可以在這裏看到,兩日行需要合併和狀態顯示列爲XXX,而不是2個單獨的行。

下面的屏幕截圖顯示了一個示例。突出顯示黃色,顯示的是PM,但應該顯示XXX,因爲每小時有1 PM和AM。

Screenshot of what is needed

我怎樣才能得到它顯示XXX時,有一個小時和AM或每小時和PM?

謝謝!

+1

你有可能發佈你的創建表語句和每個表的一些示例數據嗎?或者甚至用一些示例數據創建一個sql小提琴? – Taryn

回答

2

我會將複雜的邏輯分成兩步,使用IntermediateBookings CTE將邏輯減少到兩列has_amhas_pm。這些更容易計算,並且從這些最終輸出也很容易計算。理論上,你可以改進原始陳述的CASE表達式,以包含更多的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 - 能夠留你擁有了它。

但是,由於我沒有可用的表格,因此無法檢查語法錯誤以及結果是否符合要求。一些調整可能是必要的。

+0

完美,謝謝! – dynamicuser