2014-01-30 3 views
0

시간에 따라 집계 레코드를 수행 할 쿼리가 있지만 오류가 있습니다.시간별 집계 기록

내 상황 : 나는 1730까지 0900에서 MySQL의 DB 적이있는 분당 5.6 하나의 기록을 주식 시장 데이터를 저장, 즉 하루에 511 개 기록이다

enter image description here 나는 서로 다른 시간에 대한 이러한 데이터를 집계 할 필요가

프레임의이 5 분 가정하자 그래서

volume5min -> 합 볼륨 0900 : 0904

open5min은 - 0900 레코드 (범위 제 개방 값)

close5min 용> 오픈 값 - 0900 년> 최대 값 - 0904 레코드 (범위에서 최종 폐 값)

high5min 용> 종가 0904 범위

low5min-0904 범위

등으로 0900 년> 최저값.

나는 이러한 목표를 달성하기 위해 쿼리를 가지고,하지만 난 개폐 집계 값의 오류를 얻을

SELECT 
    floor(cast(time as SIGNED)/5) as timeInterval, 
    date, 
    time, 
    MAX(high) AS high, 
    MIN(low) as low, 
    SUM(volume) as volume, 
    (select 
      open 
     from 
      atlantia a2 
     where 
      a1.time = a2.time 
     order by time 
     limit 1) as open, 
    (select 
      close 
     from 
      atlantia a2 
     where 
      a1.time = a2.time 
     order by time desc 
     limit 1) as close 
FROM 
    atlantia a1 
GROUP BY date , timeInterval 

이것은 내가이

enter image description here

열린 쿼리를 실행하고 가까이 갈 것입니다 다른 열은 좋은 것처럼 보이지만 정확하게 집계되지는 않습니다.

무엇보다, 같은 I 1000, 1100이 지금은 또한이 등등 동안해야 0900부터 시작

enter image description here

아래의 60 분의 예로서 내가 잘못된 시간을 얻을 집계 기간을 변경 1020, 1140 등

열 유형은 다음과 같습니다

날짜 : CHAR 시간 : CHAR 모든 나머지는 DOUBLE하지만 정수 볼륨입니다.

이 쿼리를 수정하여 값을 올바르게 집계하는 방법은 무엇입니까?

편집 : 모든는 마지막 쿼리를 확인하기 위해, 나는 수동으로 하나의 시간을 확인하고이 내가

enter image description here

조회에 가까운 값에 대한 차이를 반환 받아야 올바른 값입니다 나머지는

enter image description here

닫기 값이 시간 betwee을 위해, 즉 시간 프레임의 마지막 기록해야 괜찮아 n 0900 및 0959 닫기는 닫기 열의 0959 값입니다.

편집 2 : 그것은 트릭이 어디에 내가 발견 한 지금은 모든 것이 잘 작동이 쿼리 보인다

SELECT 
Sub1.timeInterval, 
a1.date, 
MIN(a1.time), 
MAX(a1.high) AS high, 
MIN(a1.low) as low, 
SUM(a1.volume) as volume, 
a2.open as open, 
a3.close as close 
FROM atlantia a1 
INNER JOIN 
(
SELECT floor((cast(SUBSTRING(time,1,2) AS SIGNED) * 60 + cast(SUBSTRING(time,3,2) AS SIGNED)) /60) AS timeInterval, MIN(time) AS minTime, MAX(time) AS maxtime 
FROM atlantia 
GROUP BY timeInterval 
) Sub1 
ON floor((cast(SUBSTRING(a1.time,1,2) AS SIGNED) * 60 + cast(SUBSTRING(a1.time,3,2) AS SIGNED)) /60) = Sub1.timeInterval 
INNER JOIN atlantia a2 ON a2.time = Sub1.minTime AND a1.date = a2.date 
INNER JOIN atlantia a3 ON a3.time = Sub1.maxtime AND a1.date = a3.date 
GROUP BY a1.date , timeInterval 

내가, 서로 다른 시간 프레임 즉 오분 집계하려면?/60을/5와 함께 둘 다 변경합니까?

감사합니다.

+0

내 마지막 쿼리가 60 분 동안 잘 작동 , 5 분, 10 분 등등. 홀수 시간 프레임 구분에 대한 집계 문제 (예 : 7 분 또는 11 분)가 있습니다. –

답변

1

나는 몇 가지 문제점을 발견 할 수 있습니다.

시간을 문자 입력란에 저장하고 10시 20 분에 서명 한 상태로 전송하면 10 * 60 분 + 20 분이 아닌 1020으로 처리됩니다. 따라서 60으로 나누면 10:00은 16이고 10:20은 17이므로 코드에서 2 개의 다른 시간 간격입니다.

다른 문제는 GROUP BY 절에 지정되지 않은 채 필드로 시간을 반환했기 때문입니다. 반환 할 시간 값은 알 수없는 행 (일반적으로 처음이지만 항상은 아님)에서 나옵니다. MIN (시간)을 지정하는 것이 가장 쉬운 방법 일 것입니다.

SELECT 
    floor((cast(SUBSTRING(time,1,2) AS SIGNED) * 60 + cast(SUBSTRING(time,3,2) AS SIGNED)) /60) AS timeInterval, 
    date, 
    MIN(time), 
    MAX(high) AS high, 
    MIN(low) as low, 
    SUM(volume) as volume, 
    (select 
      open 
     from 
      atlantia a2 
     where 
      a1.time = a2.time 
     order by time 
     limit 1) as open, 
    (select 
      close 
     from 
      atlantia a2 
     where 
      a1.time = a2.time 
     order by time desc 
     limit 1) as close 
FROM 
    atlantia a1 
GROUP BY date , timeInterval 

하위 쿼리를 제거하기 위해 SQL을 정리할 수는 있습니다. 편집

는 연극을했다이 그것을 할 수 있지만 효율성의 확실하지 않은 및 테이블없이 나는 그것을 테스트 할 수 없습니다 : -

SELECT 
    Sub1.timeInterval, 
    a1.date, 
    MIN(a1.time), 
    MAX(a1.high) AS high, 
    MIN(a1.low) as low, 
    SUM(a1.volume) as volume, 
    MIN(a2.open) as open, 
    MIN(a3.close) as close 
FROM atlantia a1 
INNER JOIN 
(
    SELECT floor((cast(SUBSTRING(time,1,2) AS SIGNED) * 60 + cast(SUBSTRING(time,3,2) AS SIGNED)) /60) AS timeInterval, MIN(time) AS minTime, MAX(time) AS maxtime 
    FROM atlantia 
    GROUP BY timeInterval 
) Sub1 
ON floor((cast(SUBSTRING(a1.time,1,2) AS SIGNED) * 60 + cast(SUBSTRING(a1.time,3,2) AS SIGNED)) /60) = Sub1.timeInterval 
INNER JOIN atlantia a2 ON a2.time = Sub1.minTime AND a1.date = a2.date 
INNER JOIN atlantia a3 ON a3.time = Sub1.minTime AND a1.date = a3.date 
GROUP BY a1.date , timeInterval 
+0

@ Kickstart ... 감사합니다. 코드가 시간 간격 문제를 해결했지만 여는 값과 닫은 값이 올바르지 않습니다. –

+0

어떤 시점의 시작과 일치하는 행에 대해 공개적이고 가까운 값을 얻고 있지만 날짜는 확인하지 않는 것이 문제입니다. 나는 더 나은 해결책으로 연극을 가질 것이다. – Kickstart

+0

@Albertoacepsut - 빠른 재생 – Kickstart