2011-01-20 4 views
1

Предположим, что у вас есть программа, которая регистрирует (timestamp, stock_price) базу данных SQL каждые 30 секунд, и вы хотите генерировать графики цены акций в разные временные рамки. Если вы планируете измерения в течение 1 часа, все будет в порядке, чтобы использовать все 120 образцов, взятых за это время. Однако, если вы хотите запланировать цену за 1 год, вы, очевидно, не захотите вытащить более 1 миллиона образцов из базы данных. Было бы лучше вытащить из базы данных некоторое представительное подмножество образцов.Под выборка SQL-хранимых данных для графиков

Это напоминает мне технику уровня детализации в компьютерной графике - поскольку вы двигаетесь дальше от 3d модели, можно использовать более низкую версию модели.

Существуют ли общие методы представления информации о деталях детализации в базе данных или для быстрого запроса равномерно распределенного подмножества данных (например, дайте мне 100 равномерно распределенных выборок с января 2009 года)?


Решение, с которым я столкнулся, заключается в том, чтобы включить столбец 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 строк
  • Клиент должен знать, чтобы указать подходящую уровень_детализации Constraint
  • Некоторые процесс должен отвечать за создание усредненных строк, образцы добавляются в таблицу
+0

Нет ли причин, по которым вы видите финансовые диаграммы, показывающие как Высокий, Низкий, Закрытый, Открытый. он показывает вам тренд (тренд - ваш друг) и движение в течение дня, которое легко увидеть в течение определенного периода времени. – u07ch

ответ

2

Для SQL Server вы можете использовать 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