2016-10-30 2 views
0

takenOn (datetime - primary key), sleepDay (date)type (int)의 세 열이있는 MySQL 테이블이 있습니다. 이 테이블에는 잠자리에 들었을 때부터 잠자리에들 때까지의 잠 데이터가 포함됩니다 (1 분 간격으로).연속 된 행 발생 횟수

예를 들어 내가 10 월 29 일 오후 11시에 잠자리에 들고 10 월 30 일 오전 6시에 일어나면 420 레코드 (7 시간 * 60 분)가됩니다. takenOn의 범위는 2016-10-29 23:00:00에서 2016-10-30 06:00:00까지입니다. sleepDay은 420 레코드 모두에 대해 2016-10-30입니다. type는 내 수면의 "품질"입니다 (1 = 잠 들어 있음, 2 = 불안하지 않음, 3 = 깨어 있음). 나는 얼마나 많은 것을 얻으려고 노력하고있다 나는 쉬지 않고 깨어 있었는데, 나는 여러 번 타입 = 2 (또는 타입 = 3)을 보았을 때 계산할 수 있었다. 연속적으로.

지금까지 하루 만 작동하는 다음 쿼리가 필요합니다. 이것이 올바른/"효율적인"방법인가요 (이 방법은 takenOn에 "간격"이없는 데이터가 있어야 함)? 또한 가능한 모든 계산을 위해 어떻게 확장 할 수 있습니까? sleepDays? http://sqlfiddle.com/#!9/b33b4/3

감사합니다 -

SELECT 
    sleepDay, 
    SUM(CASE WHEN type = 2 THEN 1 ELSE 0 END) AS TimesRestless, 
    SUM(CASE WHEN type = 3 THEN 1 ELSE 0 END) AS TimesAwake 
FROM 
    (SELECT s1.sleepDay, s1.type 
    FROM sleep s1 
    LEFT JOIN sleep s2 
     ON s2.takenOn = ADDTIME(s1.takenOn, '00:01:00') 
    WHERE 
     (s2.type <> s1.type OR s2.takenOn IS NULL) 
     AND s1.sleepDay = '2016-10-30' 
    ORDER BY s1.takenOn) a 

나는 SQL 바이올린을 만들었습니다!

답변

1

당신이 알고있는 가정하에 당신의 자신의 솔루션은 꽤 괜찮습니다.

여기에 대체 솔루션이 제시되어 있으며 시리즈의 차이점을 잘 처리 할 수 ​​있으며 한 번에 하루 이상 사용할 수 있습니다.

단점

는 표준이 아닌 MySQL의 기능 (변수의 인라인 사용)에 더 크게 의존한다는 것입니다 :

select sleepDay, 
     sum(type = 2) TimesRestless, 
     sum(type = 3) TimesAwake 
from (
    select @lagDay as lagDay, 
      @lagType as lagType, 
      @lagDay := sleepDay as sleepDay, 
      @lagType := type as type 
    from (select * from sleep order by takenOn) s1, 
      (select @lagDay := '', 
        @lagType := '') init 
    ) s2 
where lagDay <> sleepDay 
    or lagType <> type 
group by sleepDay 

은 그것이 자신의 두 번째 select 문을 선택하는 데 도움이 될 수 있습니다 어떻게 작동하는지 볼 수 있습니다. 가장 안쪽의 select은 중간 쿼리가 그 순서대로 레코드를 처리하도록하기 위해 order by 절을 가져야하며, 이는 해당 위치에서 발생하는 변수 할당에서 중요합니다.

업데이트 된 내용은 SQL fiddle입니다.

+0

굉장! 감사합니다 - 이것은 완벽하게 작동합니다! –