2

以下の SQL クエリは、教師の空き状況を表示することになっています。午前、午後、または終日の 3 つの予約タイプがあります。午前中の予約がある場合、セル内のテキストは PM と表示され、午後の予約がある場合は AM と表示され、終日予約の場合、または午前と午後の両方の予約がある場合は「xxx」と表示されます。

これは、午前 1 時、午後 1 時、または 1 日の予約がある場合はすべて正常に機能しますが、同じ日の午前 1 時と午後 1 時の場合、MIN() を使用しているため、XXX は表示されません。最小の予約ではなく、すべての予約を 1 日で評価するにはどうすればよいですか? (コードの木曜日のセクションで、私が何を意味するかを示そうとしたことがわかります。

SQL:

with CTE_D as 
( 
   SELECT 
      DATEADD(ww, DATEDIFF(ww,0,GETDATE()), 0) as BookingDate 

   UNION ALL

   SELECT
      DATEADD(day, 1, BookingDate) 
   FROM
      CTE_D 
   WHERE
      BookingDate < DATEADD(ww, DATEDIFF(ww,0,GETDATE()), 6) 
)
SELECT 
    t.ID, t.Firstname, 
    t.Surname, tb.Band, t.Telephone, t.Mobile, t.Teacher, t.TeacherAssistant, t.PrimarySchool, t.SecondarySchool,
    MIN(CASE WHEN bd.DayText = 'Monday' AND bd.BookingDuration = 0 THEN 'PM' ELSE 'Full Day' END) "Monday", 
    MIN(CASE WHEN bd.DayText = 'Tuesday' AND bd.BookingDuration = 0 THEN 'PM' ELSE 'Full Day' END) "Tuesday", 
    MIN(CASE WHEN bd.DayText = 'Wednesday' AND bd.BookingDuration = 0 THEN 'PM' ELSE 'Full Day' END) "Wednesday", 
    MIN(CASE WHEN bd.DayText = 'Thursday' AND bd.BookingDuration = 0 THEN 'PM' WHEN bd.DayText = 'Thursday' AND bd.BookingDuration = 1 THEN 'AM' WHEN bd.DayText = 'Thursday' AND bd.BookingDuration = 2 or (bd.BookingDuration = 1 and bd.BookingDuration = 0) THEN 'xxx' END) "Thursday", 
    MIN(CASE WHEN bd.DayText = 'Friday' AND bd.BookingDuration = 0 THEN 'PM' ELSE 'Full Day' END) "Friday",
    Notes 
        FROM Teachers t 
        cross join CTE_D d 
        left join BookingDays bd 
            on t.ID = bd.TeacherID and 
               bd.BookingDate = d.BookingDate 
        left join BookingDurations bds 
            on bd.BookingDuration = bds.ID 
        left join TeacherBands tb on t.Band = tb.ID
        WHERE t.Active = 0 and (t.Status = 0 or t.Status = 1) and (bd.Status = 0 or bd.Status IS NULL) and PrimarySchool = 1
        GROUP BY Firstname, Surname, t.Telephone, t.Mobile, t.Notes, tb.Band, t.ID, t.Teacher, t.TeacherAssistant, t.PrimarySchool, t.SecondarySchool, t.Nursery, t.Reception, t.Year1, t.Year2, t.Year3, t.Year4, t.Year5, t.Year6, t.Year7, t.Year8, t.Year9, t.Year10, t.Year11, t.ALevel
        ORDER BY Surname, Firstname ASC

表の列:

ID | Firstname | Surname | Band | Telephone | Mobile | Teacher | Teacher Assistant | PrimarySchool | SecondarySchool | KeyStage | Mon | Tues | Wed | Thurs | Fri | Notes

ありがとう、マット

4

1 に答える 1

4

問題は、別々にする必要がある2つの操作を同時に実行しようとしていることだと思います(平日を確認し、予約期間を確認します)。これを行うために、私はあなたの予約期間を次のように仮定しました:

  • 0 - 午後
  • 午前1時
  • 2 - 終日

これが正しくない場合は、クエリを少し調整する必要がありますが、これで正しい方向に進むはずです。また、予約テーブルにレコードがないということは、利用できないことを意味すると想定しました。

SET LANGUAGE British;

WITH Bookings AS
(   SELECT  BookingDays.TeacherID,
            [WeekDay] = DATENAME(WEEKDAY, BookingDate),
            [Status] = CASE WHEN BookingDuration = 0 THEN 'PM' WHEN BookingDuration = 1 THEN 'AM' ELSE 'Full Day' END
    FROM    BookingDays
), PivotedBookings AS
(   SELECT  *
    FROM    Bookings
            PIVOT
            (   MAX([Status])
                FOR [WeekDay] IN ([Monday], [Tuesday], [Wednesday], [Thursday], [Friday])
            ) pvt
)
SELECT  t.ID, 
        t.Firstname, 
        t.Surname, 
        tb.Band, 
        t.Telephone, 
        t.Mobile, 
        t.Teacher, 
        t.TeacherAssistant, 
        t.PrimarySchool, 
        t.SecondarySchool,
        Monday = COALESCE(pb.Monday, 'Not Available'),
        Tuesday = COALESCE(pb.Tuesday, 'Not Available'),
        Wednesday = COALESCE(pb.Wednesday, 'Not Available'),
        Thursday = COALESCE(pb.Thursday, 'Not Available'),
        Friday = COALESCE(pb.Friday, 'Not Available'),
        t.Notes
FROM    Teachers t
        LEFT JOIN PivotedBookings pb
            ON pb.TeacherID = t.ID
        LEFT JOIN TeacherBands tb
            ON tb.ID = t.Band;

SQL Fiddle の削減例


補遺

この行を読んだ後:

WHEN bd.DayText = 'Thursday' AND bd.BookingDuration = 2 or (bd.BookingDuration = 1 and bd.BookingDuration = 0)

予約期間が 2 か、テーブル内の同じ教師と日付の午前と午後のエントリのいずれかです。この場合、データを 2 回ピボットする必要があるため、最初の CTE は次のようになります。

WITH Bookings AS
(   SELECT  BookingDays.TeacherID,
            [WeekDay] = DATENAME(WEEKDAY, BookingDate),
            [Status] = CASE WHEN [2] > 0 THEN 'Full Day'
                            WHEN [0] > 0 AND [1] > 0 THEN 'xxx'
                            WHEN [0] > 0 THEN 'PM'
                            WHEN [1] > 0 THEN 'AM'
                        END

    FROM    (   SELECT  TeacherID, BookingDate, BookingDuration, [X] = 1
                FROM    BookingDays
            ) BookingDays
            PIVOT
            (   SUM(X)
                FOR BookingDuration IN ([0], [1], [2])
            ) pvt
)

SQL Fiddle の更新された例 (Teacher 1 の木曜日に注意)

于 2013-02-14T16:09:43.290 に答える