2014-04-14 1 views
2

센서 데이터를 받아들이고 플롯하는 Rails 4 앱을 작성했습니다. 때로는 시간당 10 포인트가 있습니다 (그러나이 숫자는 고정되어 있지 않습니다). 필자는 모든 데이터 포인트를 얻기 위해 데이터를 플로팅하고 Points.all의 간단한 쿼리를 수행합니다.레일에서 일정 기간 동안 한 시간에 한 레코드 만 반환합니다.

쿼리 크기를 줄이기 위해 시간당 하나의 레코드 만 반환하고 싶습니다. 어떤 레코드가 반환되는지는 중요하지 않습니다. created_at 필드를 사용하여 매 시간 첫 번째 레코드는 괜찮습니다.

어떻게 이렇게 쿼리를 구성합니까?

+0

데이터를 어디에 저장합니까? 테이블은 어떻게 생겼지. – drKreso

+0

이것은 개발 환경에서 생산 및 Sqlite의 mySql에 있습니다. 클래스 이름은 표준 레일 타임 스탬프를 사용하는 Point입니다. 그래서 Point.create_at는 객체가 생성 된 datetime을 반환합니다. – bodagetta

답변

1

첫 번째 값을 얻을 수 있지만 평균값이 더 좋을 수도 있습니다. 시간 단위로 그룹화하면됩니다. 나는이 점에서 SQLite는 구문하지만 뭔가 약 100 % 아니다 :

connection.execute("SELECT AVG(READING_VALUE) FROM POINTS GROUP BY STRFTIME('%Y%m%d%H0', CREATED_AT)") 
+0

레일에서 작동합니까? 저는 Point와 같은 것에 익숙합니다. (....) 내 쿼리 구문에 – bodagetta

+0

@bodagetta 모델에 배치되는 한 (연결은 활성 레코드 기반에 속하기 때문에) 작동합니다. 나는 "순수한"AR 버전은 다음과 같을 것이라고 생각한다 : * Point.average (reading_value) .group ("strftime ('% Y % m % d % H0', created_at")'* (untested) * –

+0

"실제"레일 "방식으로. – drKreso

0

this answer에서 영감을 여기에 (당신이 평균을하지 않으려는 경우) 그 시간에 최신 기록을 검색하는 대안은 다음과 같습니다

Point.from(
      Point.select("max(unix_timestamp(created_at)) as max_timestamp") 
       .group("HOUR(created_at)") # subquery 
     ) 
    .joins("INNER JOIN points ON subquery.max_timestamp = unix_timestamp(created_at)") 

이 다음 쿼리가 발생합니다 : 당신이하는 좋아하는 경우

SELECT `points`.* 
FROM (
     SELECT max(unix_timestamp(created_at)) as max_timestamp 
     FROM `points` 
     GROUP BY HOUR(created_at) 
    ) subquery 
INNER JOIN points ON subquery.max_timestamp = unix_timestamp(created_at) 

또한, 시간의 첫 번째 레코드를 얻기 위해 대신 MIN을 사용할 수 있습니다 좋은데.

+0

나는이 오류가있어 !! # bodagetta

관련 문제