2011-02-22 5 views
1

나는이시간 간격 계산을 사용하여 SQL

CREATE TABLE IF NOT EXISTS `vals` (
    `DT` datetime NOT NULL, 
    `value` INT(11) NOT NULL, 
    PRIMARY KEY (`DT`) 
); 

DT는 같은 MySQL의 테이블이 시간에 고유 한 날짜입니다 가지고

데이터 샘플 : 내가 얻을 필요가

INSERT INTO `vals` (`DT`,`value`) VALUES 
('2011-02-05 06:05:00', 300), 
('2011-02-05 11:05:00', 250), 
('2011-02-05 14:35:00', 145), 
('2011-02-05 16:45:00', 100), 
('2011-02-05 18:50:00', 125), 
('2011-02-05 19:25:00', 100), 
('2011-02-05 21:10:00', 125), 
('2011-02-06 00:30:00', 150); 

다음과 같은 내용 :

start|end|value 
NULL,'2011-02-05 06:05:00',300 
'2011-02-05 06:05:00','2011-02-05 11:05:00',250 
'2011-02-05 11:05:00','2011-02-05 14:35:00',145 
'2011-02-05 14:35:00','2011-02-05 16:45:00',100 
'2011-02-05 16:45:00','2011-02-05 18:50:00',125 
'2011-02-05 18:50:00','2011-02-05 19:25:00',100 
'2011-02-05 19:25:00','2011-02-05 21:10:00',125 
'2011-02-05 21:10:00','2011-02-06 00:30:00',150 
'2011-02-06 00:30:00',NULL,NULL 

나는 다음과 같은 쿼리를 시도 :

SELECT T1.DT AS `start`,T2.DT AS `stop`, T2.value AS value FROM (
    SELECT DT FROM vals 
) T1 
LEFT JOIN (
    SELECT DT,value FROM vals 
) T2 
ON T2.DT > T1.DT ORDER BY T1.DT ASC 

을하지만 많은 행에 반환 (29 대신 9) 결과와 나는이 사용하는 SQL을 제한 할 수있는 방법을 찾을 수 없습니다 콜드. 그것은 MySQL에서 가능합니까? 두 개의 서로 다른과를 ​​출력을

select @myvar as start, end, value, @myvar := end as next_rows_start 
from vals 

변수가 순서대로 왼쪽에서 오른쪽으로 해석되므로 두 개의 참조 (next_rows_start 시작) @myvar하기 :

당신은 서버 측 변수를 사용할 수 있습니다

답변

4

를 사용하여 하위 쿼리를

SELECT 
    (
    select max(T1.DT) 
    from vals T1 
    where T1.DT < T2.DT 
) AS `start`, 
    T2.DT AS `stop`, 
    T2.value AS value 
FROM vals T2 
ORDER BY T2.DT ASC 

변수를 사용하는 MySQL 특정 솔루션을 사용할 수도 있습니다.

SELECT CAST(@dt AS DATETIME) AS `start` , @dt := DT AS `stop` , `value` 
FROM (SELECT @dt := NULL) dt, vals 
ORDER BY dt ASC 

하지만 오 그것은 정확하게

  • 주문 인한 있어야 의한 그렇지 않으면 변수는이 두 번 실행, 그렇지 않은 경우, 제대로 변수를 설정하는 하위 쿼리를 사용하여 쿼리 내에서 무효가 될 필요가
  • 롤하지 않습니다 두 번째로 NULL로 시작하지 않습니다.
+0

'순수 SQL'버전이 작동하지만 (노력과 프로파일 링 및 색인 작성에도 불구하고) O (n^2) . 18,000 개의 행 테이블이 주어지면 pure SQL 버전은 580 초가 걸리며, 변수가있는 MySQL 관련 버전은 2.5 초 정도 걸립니다. 두 버전을 모두 제공해 주셔서 감사합니다. –

0

그것을 시뮬레이션 값.

직전 null로 @myvar을 다시 기억하고/쿼리 후, 그렇지 않으면 두 번째 이후 실행은 잘못된 첫 번째 행이되거나 :

select @myvar := null 
0

테이블에 DT (동일한 순서)의 시간에 해당하는 실행 ID 열이 있으면이 방법이 더 쉬울 것입니다. 테이블을 변경하고 싶지 않으면 임시 직원을 사용할 수 있습니다.

drop table if exists temp; 

CREATE TABLE temp (
    `id` INT(11) AUTO_INCREMENT, 
    `DT` datetime NOT NULL, 
    `value` INT(11) NOT NULL, 
    PRIMARY KEY (`id`) 
); 

insert into temp (DT,value) select * from vals order by DT asc; 

select t1.DT as `start`, t2.DT as `end`, t2.value 
from temp t2 
left join temp t1 ON t2.id = t1.id + 1; 
+0

좋은 생각이지만 내 경우에는 적합하지 않습니다 (실제 테이블에 추가 필드가 있음). –

관련 문제