2011-01-20 2 views
1

SQL 데이터베이스에 (timestamp, stock_price)를 30 초마다 기록하고 다양한 시간 규모에 대한 주가 표시를 생성하려는 프로그램이 있다고 가정하십시오. 1 시간 범위에서 측정 값을 플롯하면 해당 시간 동안 120 개의 샘플을 모두 사용해도됩니다. 그러나 1 년 범위에서 가격을 그래프로 나타내려면 데이터베이스에서 100 만 개 이상의 샘플을 가져 오지 않으려 고합니다. 데이터베이스에서 일부 샘플의 대표 하위 집합을 추출하는 것이 좋습니다.플롯에 대한 서브 샘플링 SQL 저장 데이터

이것은 컴퓨터 그래픽의 세부 묘사 기법을 생각 나게합니다. 3d 모델에서 멀리 떨어지면 더 낮은 충실도의 모델을 사용할 수 있습니다.

데이터베이스에 상세 수준 정보를 표시하거나 균등하게 간격을 둔 데이터 하위 집합을 신속하게 쿼리하기위한 일반적인 기술이 있습니까 (예 : 2009 년 1 월부터 100 개의 균일 한 샘플을 제공)?


해결책은 데이터베이스 테이블에 level_of_detail 열을 포함시키는 것입니다. level_of_detail = 0이면, 행은 단일 순간 샘플을 보유합니다. level_of_detail = n 인 경우, 행에는 데이터의 마지막 (sample_interval * (2^n)) 초의 평균이 포함되며이 레벨에는 1/(2^n) 개의 행이 있습니다. 테이블에는 (level_of_detail, timestamp)에 대한 인덱스가 있으며, 플롯을 생성하려면 원하는 샘플 수를 기반으로 적절한 level_of_detail 값을 계산하고 해당 제약 조건을 사용하여 쿼리합니다. 단점은 다음과 같습니다 N 개의 샘플에 대한

  • 는 표 2를 저장해야 * N 행 클라이언트는
  • 일부 과정으로 평균 행을 구축하기위한 책임을 질 필요가 적절한 level_of_detail 제약 조건을 지정하기 위해 알고 있어야합니다
  • 샘플이 표에 추가됩니다.
+0

높음, 낮음, 닫음, 열림과 같은 금융 차트가 표시되는 이유가 없습니까? 일정 기간 동안 쉽게 볼 수있는 추세 (추세는 친구)와 그날의 움직임을 보여줍니다. – u07ch

답변

2

ntile을 사용할 수 있습니다. 이 명령은 데이터 집합을 정렬 한 다음 N 개의 다른 그룹으로 분할하여 첫 번째 그룹에 대해 1을 반환하고 마지막 그룹에 대해 N을 반환합니다.

select MIN(MeasureTime) as PeriodStart 
,  MAX(MeasureTime) as PeriodEnd 
,  AVG(StockPrice) as AvgStockPrice 
from (
     select MeasureTime 
     ,  StockPrice 
     ,  NTILE(100) over (order by MeasureTime) as the_tile 
     from @t YourTable 
     ) tiled 
group by 
     the_tile 

정확히 100 개의 행을 반환합니다. 다음은 쿼리를 시도하는 데 유용한 테스트 데이터의 사본입니다.

declare @t table (MeasureTime datetime, StockPrice int) 
declare @dt date 
set @dt = '2010-01-01' 
while @dt < '2011-01-01' 
    begin 
    insert @t values (@dt, DATEDIFF(day,'2010-01-01',@dt)) 
    select @dt = DATEADD(day,1,@dt) 
    end 
관련 문제