子图采样SQL存储的数据

时间:2011-01-20 18:26:59

标签: sql plot graphing level-of-detail

假设您有一个程序每30秒将一个日志(timestamp,stock_price)记录到SQL数据库,并且您想要生成不同时间尺度的股票价格图。如果您在1小时范围内绘制测量值,则可以使用在此期间拍摄的所有120个样本。但是,如果您想在1年范围内绘制价格,您显然不希望从数据库中提取超过100万个样本。最好将一些代表性的样本子集从数据库中提取出来。

这让我想起计算机图形学中的细节水平技术 - 当你从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约束
  • 当样本添加到表格
  • 时,某些流程需要负责构建平均行

1 个答案:

答案 0 :(得分: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