-1

我有一个名为 CLASSTIMES 的表,它有一个 bool 类型的列,用于一周中的每一天(SUNDAY、MONDAY、TUESDAY...等),还包含一个 STARTDATE 和一个 ENDDATE 列。例如,我将有一行选择 MONDAY 和 WEDNESDAY,STARTDATE 为 2013 年 6 月 3 日,ENDDATE 为 2013 年 6 月 26 日。

我想要做的是创建一个 SPROC 将一系列行插入到一个名为 CLASSCALENDAR 的表中,该表包含每个选定日期列的 StartDate 和 EndDate 之间的所有日期。

例如,如果用户从 ClassTimes 表中选择 Monday 和 Wednesay,它将生成:

行日期
1 2013-06-03
2 2013-06-10
3 2013-06-17
4 2013-06-24
5 2013-06-05
6 2013-06-12
7 2013-06-19
8 2013-06-26

我试图设置它,但它有点过头了。任何帮助将非常感激。

4

1 回答 1

0

这是一个可能对您有用的 SQL 语句。

SELECT course,
       Convert(varchar(25), course_date, 101) AS course_date
  FROM (SELECT course_no AS course,
               DATEADD(dd, rn-1, startdate) AS course_date,
               DATENAME(dw, DATEADD(dd, rn-1, startdate)) AS dow
          FROM (SELECT row_number() OVER (ORDER BY c1) AS rn
                  FROM dummy) sub1,
               classtimes
         WHERE rn <= (DATEDIFF(dd, startdate, enddate)+1)
       ) list_of_dates,
       (SELECT course_no,
               (CASE monday WHEN 1 THEN 'Monday' END) AS dow
          FROM classtimes
        UNION
        SELECT course_no,
               (CASE tuesday WHEN 1 THEN 'Tuesday' END)
          FROM classtimes
        UNION
        SELECT course_no,
               (CASE wednesday WHEN 1 THEN 'Wednesday' END)          
          FROM classtimes
        UNION
        SELECT course_no,
               (CASE thursday WHEN 1 THEN 'Thursday' END)
          FROM classtimes
        UNION
        SELECT course_no,
               (CASE friday WHEN 1 THEN 'Friday' END)
          FROM classtimes
        UNION
        SELECT course_no,
               (CASE saturday WHEN 1 THEN 'Saturday' END)
          FROM classtimes
        UNION
        SELECT course_no,
               (CASE sunday WHEN 1 THEN 'Sunday' END)
          FROM classtimes
        ) class_days
 WHERE list_of_dates.dow = class_days.dow
   AND list_of_dates.course = class_days.course_no
 ORDER BY course_no,
          course_date

我使用了查询

SELECT course_no AS course,
       DATEADD(dd, rn-1, startdate) AS course_date,
       DATENAME(dw, DATEADD(dd, rn-1, startdate)) AS dow
  FROM (SELECT row_number() OVER (ORDER BY c1) AS rn
          FROM dummy) sub1,
       classtimes
 WHERE rn <= (DATEDIFF(dd, startdate, enddate)+1)

为每门课程生成开始日期和结束日期之间所有日期的列表。为了使此查询正常工作,虚拟表必须包含至少与每门课程的开始日期和结束日期之间的天数一样多的行。因此,其结果是每门课程的开始日期和结束日期之间的天数列表,以及该日期的星期几。

| COURSE | COURSE_DATE |       DOW |
------------------------------------
|   MATH |  06/03/2013 |    Monday |
|   MATH |  06/04/2013 |   Tuesday |
|   MATH |  06/05/2013 | Wednesday |
|   MATH |  06/06/2013 |  Thursday |
|   MATH |  06/07/2013 |    Friday |
.........
.........
|   MATH |  06/24/2013 |    Monday |
|   MATH |  06/25/2013 |   Tuesday |
|   MATH |  06/26/2013 | Wednesday |

然后,我有一个子查询,它使用一系列 UNION 从 classtimes 表中获取星期几列,并生成将举行课程的星期几。然后,我只需将 list_of_dates 子查询与 class_days 子查询结合起来,即可获取要举行课程的日期。

|  COURSE | COURSE_DATE |
-------------------------
|    MATH |  06/03/2013 |
|    MATH |  06/05/2013 |
|    MATH |  06/10/2013 |
|    MATH |  06/12/2013 |
|    MATH |  06/17/2013 |
|    MATH |  06/19/2013 |
|    MATH |  06/24/2013 |
|    MATH |  06/26/2013 |

我确信有一种更有效/优雅的方法可以从 classtimes 表(class_days 子查询)中为班级生成一周中的日期列表,但我想不出一个。

于 2013-05-21T23:34:13.320 回答