我有一个名为CLASSTIMES的表,它有一个bool类型的列,用于一周中的每一天(SUNDAY,MONDAY,TUESDAY ......等),还包含一个STARTDATE和ENDDATE列。例如,我有一行选择MONDAY和WEDNESDAY,其2013年6月3日的STARTDATE和2013年6月26日的ENDDATE。
我希望能够做的是创建一个SPROC,将一系列行插入一个名为CLASSCALENDAR的表中,该表包含每个选定日期列的StartDate和EndDate之间的所有日期。
例如,如果用户从ClassTimes表中选择了Monday和Wednesay,它将生成:
Row Date 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
我试图设置它,但它有点超过我的头脑。任何帮助将不胜感激。
答案 0 :(得分: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)
生成每个课程的startdate和enddate之间所有日期的列表。为了使此查询正常工作,虚拟表必须至少包含与每个课程的startdate和enddate之间的天数一样多的行。因此,结果是每个课程的开始日期和结束日期之间的天数列表,以及该日期的星期几。
| 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子查询)生成类的星期几列表有更高效/更优雅的方法,但我想不出一个。