需要帮助在SQL查询中实现循环

时间:2016-02-15 08:23:31

标签: sql sql-server database sql-server-2008

我的SQL Server数据库中有两个表FACULTY_RECORDS& SCHOOL_RECORDS。我有一些行,其中包含由院系填写的关于他们在表FACULTY_RECORDS中讲授的数据的行,以及包含由学校分配给各院系的时间段的行,用于对他们的科目进行讲座。

教师以格式< 10:15:00'在表格LECTURE_START_TIME中的FACULTY_RECORDS列中,学校提到格式为< 0900-1200'提供给表LECTURE_TIME_SLOTSCHOOL_RECORDS列中的教师。

现在,我有一个SQL查询,检查教师为他的特定主题输入的时间是否属于学校分配的时间段。但是,使用SQL查询我得到多个输出行,因为相同的开始时间落在多个时隙中。然而,如果讲座开始时间落在为同一主题分配的时间段内,我要求查询只提供一个输出。

请参阅我的SQL查询:

SELECT 
    a.FACULTY, 
    a.SUBJECT, 
    a.LECTURE_DATE, 
    a.LECTURE_START_TIME 
FROM
    (SELECT
         b.LECTURE_TIME_SLOT, b.FACULTY, b.SUBJECT, b.LECTURE_DATE, 
         CAST(LEFT(b.LECTURE_TIME_SLOT, 2) + ':' + RIGHT(LEFT(b.LECTURE_TIME_SLOT, 4), 2) AS TIME) AS StartHours,
         CAST(LEFT(RIGHT(b.LECTURE_TIME_SLOT, 4), 2) + ':' + RIGHT(b.LECTURE_TIME_SLOT, 2) AS TIME) AS EndHours 
     FROM 
         @FACULTY_RECORDS AS a, @SCHOOL_RECORDS AS b) AS b 
JOIN
    @FACULTY_RECORDS AS a ON a.FACULTY = b.FACULTY 
                          AND a.SUBJECT = b.SUBJECT 
                          AND a.LECTURE_DATE = b.LECTURE_DATE 
WHERE
    CAST(a.LECTURE_START_TIME AS TIME) >= b.StartHours 
    AND CAST(a.LECTURE_START_TIME AS TIME) <= b.EndHours

请参考下图:

FACULTY_RECORDS & SCHOOL_RECORDS

Outputs: Lectures not matching & matching the time slots

1 个答案:

答案 0 :(得分:0)

不清楚为什么使用2个表的隐含交叉连接(笛卡尔积)。如果有样本数据和预期结果,这确实会有所帮助。如果没有这些,这有帮助吗?

select
     f.SUBJECT
   , f.LECTURE_DATE
   , f.LECTURE_START_TIME
   , s.StartTime
   , s.EndTime
FROM FACUTLY_RECORDS f
INNER JOIN (
        SELECT
             SUBJECT
           , LECTURE_DATE
           ,  CAST(LEFT(LECTURE_TIME_SLOT, 2) 
                 + ':' 
                 + substring(LECTURE_TIME_SLOT, 3, 2) AS time) AS StartTime
           , CAST(substring(LECTURE_TIME_SLOT, 6,2)
                 + ':' 
                 + RIGHT(LECTURE_TIME_SLOT, 2) AS time) AS EndTime
        FROM SCHOOL_RECORDS
      ) s  ON f.subject = s.subject
           AND f.LECTURE_DATE = s.LECTURE_DATE
           AND CAST(f.LECTURE_START_TIME AS time) BETWEEN s.StartTime AND s.EndTime
 ;

这是一种不使用转换为时间的替代方法。尝试转换&#39; 10:00&#39;时间。它只列出两个表中的匹配,因为它使用内连接。

SELECT
      f.SUBJECT
    , f.LECTURE_DATE
    , f.LECTURE_START_TIME
    , s.StartTime
    , s.EndTime
FROM FACUTLY_RECORDS f
      INNER JOIN (
            SELECT
                  SUBJECT
                , LECTURE_DATE
                , LEFT(LECTURE_TIME_SLOT, 4) AS StartTime
                , RIGHT(LECTURE_TIME_SLOT, 4) AS EndTime
            FROM SCHOOL_RECORDS
      ) s ON f.subject = s.subject
                  AND f.LECTURE_DATE = s.LECTURE_DATE
                  AND replace(left(f.LECTURE_START_TIME,5),':','') BETWEEN s.StartTime AND s.EndTime
;  

我建议你提供更完整的测试数据,当然还有预期的结果,但仍然缺席。

queries

CREATE TABLE FACULTY_RECORDS
    ([FACULTY_NAME] varchar(4), [SUBJECT] varchar(7), [LECTURE_DATE] datetime, [LECTURE_START_TIME] varchar(8))
;

INSERT INTO FACULTY_RECORDS
    ([FACULTY_NAME], [SUBJECT], [LECTURE_DATE], [LECTURE_START_TIME])
VALUES
    ('Alex', 'Biology', '2015-01-10 00:00:00', '3:55:36'),
    ('Alex', 'Biology', '2015-01-10 00:00:00', '10:7:22'),
    ('Alex', 'Biology', '2015-01-10 00:00:00', '11:17:44')
;

CREATE TABLE SCHOOL_RECORDS
    ([FACULTY_NAME] varchar(4), [SUBJECT] varchar(7), [LECTURE_DATE] datetime, [LECTURE_TIME_SLOT] varchar(9))
;

INSERT INTO SCHOOL_RECORDS
    ([FACULTY_NAME], [SUBJECT], [LECTURE_DATE], [LECTURE_TIME_SLOT])
VALUES
    ('Alex', 'Biology', '2015-01-10 00:00:00', '0900-1200'),
    ('Alex', 'Biology', '2015-01-10 00:00:00', '0900-1200'),
    ('Alex', 'Biology', '2015-01-10 00:00:00', '0900-1200')
;