복붙노트

[SQL] 동일한 값의 연속 그룹 행 타임 스팬을 이용하여

SQL

동일한 값의 연속 그룹 행 타임 스팬을 이용하여

죄송합니다 막연한 제목 (난 그냥이 수수께끼를 설명하는 방법을 모른다)

교실에 대해 다음 스케줄 표를 보내기

╔═══════════╦════════════╦═══════════╦═══════════╦═════════╗
║ Classroom ║ CourseName ║  Lesson   ║ StartTime ║ EndTime ║
╠═══════════╬════════════╬═══════════╬═══════════╬═════════╣
║      1001 ║ Course 1   ║ Lesson 1  ║      0800 ║    0900 ║
║      1001 ║ Course 1   ║ Lesson 2  ║      0900 ║    1000 ║
║      1001 ║ Course 1   ║ Lesson 3  ║      1000 ║    1100 ║
║      1001 ║ Course 2   ║ Lesson 10 ║      1100 ║    1200 ║
║      1001 ║ Course 2   ║ Lesson 11 ║      1200 ║    1300 ║
║      1001 ║ Course 1   ║ Lesson 4  ║      1300 ║    1400 ║
║      1001 ║ Course 1   ║ Lesson 5  ║      1400 ║    1500 ║
╚═══════════╩════════════╩═══════════╩═══════════╩═════════╝

나는 그룹이 표시하는 테이블을 싶습니다

╔═══════════╦════════════╦═══════════╦═════════╗
║ Classroom ║ CourseName ║ StartTime ║ EndTime ║
╠═══════════╬════════════╬═══════════╬═════════╣
║      1001 ║ Course 1   ║      0800 ║    1100 ║
║      1001 ║ Course 2   ║      1100 ║    1300 ║
║      1001 ║ Course 1   ║      1300 ║    1500 ║
╚═══════════╩════════════╩═══════════╩═════════╝

어떤 crouse 쇼가 특정 시간 범위 동안 어떤 교실을 사용하고 기본적으로 우리는 일정에서 찾고 있습니다 ...

내 초기 생각했다 : 교실 및 CourseName에 의해 그룹과는 시작 \ 종료 시간에 대한 최대 및 최소를 가지고 있지만 나에게 과정 일 08:00부터 교실을 사용하는 경우로 보여 할 시간 범위를 제공하지 않습니다 - 16:00 중간에 절단없이.

해결법

  1. ==============================

    1.쿼리를 사용하여 각 행의 ENDTIME가 확실하지 다른 클래스 또는 물론 다른 유형의 교육 과정 범위의 상영 시간과 종료 시각 사이에 예정으로 만들기 위해 존재하고 상영을 찾기 위해 MIN 및 GROUP BY를 사용하여 결정한다.

    쿼리를 사용하여 각 행의 ENDTIME가 확실하지 다른 클래스 또는 물론 다른 유형의 교육 과정 범위의 상영 시간과 종료 시각 사이에 예정으로 만들기 위해 존재하고 상영을 찾기 위해 MIN 및 GROUP BY를 사용하여 결정한다.

    NOT 다른 CourseName 또는 CourseRoom에 상영과 종료 시각 사이 만에 귀속 ENDTIME이있는 모든 행을 검색하여 상영 및 ENDTIME 범위 사이의 "휴식"이 아니라는 것을 부분 보장하지만 존재한다.

    SELECT    
        t0.ClassRoom,
        t0.CourseName,
        MIN(t0.StartTime),
        t0.EndTime
    FROM (
        SELECT 
        t1.ClassRoom,
        t1.CourseName,
        t1.StartTime,
        (
            SELECT MAX(t2.EndTime)
            FROM tableA t2
            WHERE t2.CourseName = t1.CourseName
            AND t2.ClassRoom = t1.ClassRoom
            AND NOT EXISTS (SELECT 1 FROM tableA t3
                WHERE t3.EndTime < t2.EndTime 
                AND t3.EndTime > t1.EndTime
                AND (t3.CourseName <> t2.CourseName 
                OR t3.ClassRoom <> t2.ClassRoom)
            )
        ) EndTime
        FROM tableA t1
    ) t0 GROUP BY t0.ClassRoom, t0.CourseName, t0.EndTime
    

    http://www.sqlfiddle.com/#!6/39d4b/9

  2. ==============================

    2.당신의 SQLServer 2012를 사용하고 또는 더 나은 당신이 LAG를 사용할 수있는 경우 컬럼의 이전 값을 얻기 위해, 다음 SUM은 () OVER (ORDER BY는 ...)의 변화를 계산하는이 경우 하나, 롤링 합계를 만들 수 있습니다 실체가 앵커로 사용할 수 있습니다 CourseName,

    당신의 SQLServer 2012를 사용하고 또는 더 나은 당신이 LAG를 사용할 수있는 경우 컬럼의 이전 값을 얻기 위해, 다음 SUM은 () OVER (ORDER BY는 ...)의 변화를 계산하는이 경우 하나, 롤링 합계를 만들 수 있습니다 실체가 앵커로 사용할 수 있습니다 CourseName,

    With A AS (
      SELECT ClassRoom
           , CourseName
           , StartTime
           , EndTime
           , PrevCourse = LAG(CourseName, 1, CourseName) OVER (ORDER BY StartTime)
      FROM   Table1
    ), B AS (
      SELECT ClassRoom
           , CourseName
           , StartTime
           , EndTime
           , Ranker = SUM(CASE WHEN CourseName = PrevCourse THEN 0 ELSE 1 END)
                    OVER (ORDER BY StartTime, CourseName)
      FROM   A
    )
    SELECT ClassRoom
         , CourseName
         , MIN(StartTime) StartTime
         , MAX(EndTime) EndTime
    FROM   B
    GROUP BY ClassRoom, CourseName, Ranker
    ORDER BY StartTime
    

    SQL 휘티 d 혀라도

  3. ==============================

    3.

         CREATE TABLE Classroom(Classroom VARCHAR(100), CourseName  VARCHAR(100),  Lesson    VARCHAR(100), StartTime  VARCHAR(100), EndTime  VARCHAR(100))
     INSERT INTO Classroom
    SELECT '1001','Course 1','Lesson 1 ','0800','0900'
    UNION SELECT '1001','Course 1','Lesson 2 ','0900','1000'
    UNION SELECT '1001','Course 1','Lesson 3 ','1000','1100'
    UNION SELECT '1001','Course 2','Lesson 10','1100','1200'
    UNION SELECT '1001','Course 2','Lesson 11','1200','1300'
    UNION SELECT '1001','Course 1','Lesson 4 ','1300','1400'
    UNION SELECT '1001','Course 1','Lesson 5 ','1400','1500'
    
    SELECT * FROM Classroom
    
    ;WITH CTE_ClassRooms AS (
    SELECT *,ROW_NUMBER() over(partition by classroom,CourseName order by StartTime) AS R FROM Classroom A 
    WHERE NOT EXISTS(SELECT 1 FROM Classroom B WHERE B.Classroom = A.Classroom AND B.CourseName = A.CourseName AND B.StartTime = A.EndTime)
    UNION ALL
    SELECT B.*,R fROM CTE_ClassRooms A JOIN Classroom B ON B.Classroom = A.Classroom AND B.CourseName = A.CourseName AND A.StartTime = B.EndTime
    )
    
    --SELECT * FROM CTE_ClassRooms order by Classroom,CourseName,R
    
    SELECT Classroom,CourseName,MIN(StartTime),MAX(EndTime)
    FROM CTE_ClassRooms
    GROUP BY Classroom,CourseName,R
    
  4. from https://stackoverflow.com/questions/24244659/group-consecutive-rows-of-same-value-using-time-spans by cc-by-sa and MIT license