2015-09-16 110 views
2

我有一个数据集并希望显示它,但它可能非常巨大(数千个点),我想过滤它们。例如,此处输出的点数为1000+: enter image description here非均匀分布式数据集的NTILE替代方案

现在我使用NTILE获得近似值,但如果点不是均匀分布的,则它不起作用。而我得到这个输出(NTILE与参数100):

enter image description here

我怎样才能避免这种情况? SQL存储过程如下:

ALTER PROCEDURE [dbo].[usp_GetSystemHealthCheckData] 
    @DateFrom datetime,   
    @DateTo datetime,    
    @EstimatedPointCount int 
    with recompile 
AS 

BEGIN 
    SET NOCOUNT ON; 
    set arithabort on 

    if @DateFrom IS NULL 
     RAISERROR ('@DateFrom cannot be NULL', 16, 1) 

    if @DateTo IS NULL 
     RAISERROR ('@DateTo cannot be NULL', 16, 1)  

    if @EstimatedPointCount IS NULL 
     RAISERROR ('@EstimatedPointCount cannot be NULL', 16, 1)  

    ;With T as 
    (
     SELECT *, GroupId = NTILE(@EstimatedPointCount) over (order by GeneratedOnUtc) 
     FROM SystemHealthCheckData 
     WHERE GeneratedOnUtc between @DateFrom AND @DateTo 
    ) 

    SELECT CpuPercentPayload = AVG(CpuPercentPayload), 
      FreeRamMb = AVG(FreeRamMb), 
      FreeDriveMb = AVG(FreeDriveMb), 
      GeneratedOnUtc = CAST(AVG(CAST(GeneratedOnUtc AS DECIMAL(18, 6))) AS DATETIME) 
    FROM T 
    GROUP BY GroupId 
END 

回答

2

编辑:新方法

你可能会分裂与NTILE你的负载,然后计算各组的平均?我分成了4组。这让查询返回4个平均值。组的数量可以根据您拥有或可以完成修补的点数来计算。

事情是这样的:

DECLARE @tbl TABLE(id INT IDENTITY, nmbr FLOAT); 
INSERT INTO @tbl VALUES(5),(4.5),(4),(3.5),(3),(2.5),(2),(1.5),(1),(1.5),(1),(0.5),(0),(13),(2),(17),(5),(22),(24),(2),(3),(11); 

SELECT tbl2.* 
     ,AVG(nmbr) OVER(PARTITION BY tbl2.tile) 
FROM 
(
    SELECT tbl.* 
      ,NTILE(4) OVER(ORDER BY id) AS tile 
    FROM @tbl AS tbl 
)AS tbl2 

如果你想让它降低到组值仅你可以试试这个

SELECT AVG(nmbr),tbl2.tile 
FROM 
(
    SELECT tbl.* 
      ,NTILE(4) OVER(ORDER BY id) AS tile 
    FROM @tbl AS tbl 
)AS tbl2 
GROUP BY tbl2.tile 

--old文本 你也许要考虑滑动平均...在这个例子中,我尝试重建你的值(最后线性下降和野性跳跃)。您可以设置@pre和@post变量来设置“flatening”的等级。

总之:有一个平均值计算每个元素及其直接邻居。

注意的事实是,你必须添加一个ORDER BY避免随机结果...

DECLARE @tbl TABLE(id INT IDENTITY, nmbr FLOAT); 
INSERT INTO @tbl VALUES(5),(4.5),(4),(3.5),(3),(2.5),(2),(1.5),(1),(1.5),(1),(0.5),(0),(13),(2),(17),(5),(22),(24),(2),(3),(11); 

DECLARE @pre INT=3; 
DECLARE @post INT=3; 

SELECT tbl.* 
     ,AvgBorders.* 
     ,AvgSums.* 
     ,AvgSlide.* 
FROM @tbl AS tbl 
CROSS APPLY 
(
    SELECT [email protected] AS AvgStart 
      ,tbl.id + @post AS AvgEnd 
) AS AvgBorders 
CROSS APPLY 
(
    SELECT COUNT(nmbr) AS CountNmbr 
      ,SUM(nmbr) AS SumNmbr 
    FROM @tbl AS tbl 
    WHERE tbl.id BETWEEN AvgStart AND AvgEnd 
) as AvgSums 
CROSS APPLY 
(
    select AvgSums.SumNmbr/AvgSums.CountNmbr As AvgValue 
) As AvgSlide 
; 
+0

是的,这是关于一个滑动平均水平,但问题是我不知道应该分多少是分组。例如“我们应该从4月1日到6月1日获得100分,表明动态”。数据集有113个点。这里需要像Bresenham的线算法这样的算法来插入这个数据集。 –

+0

@AlexZhukovskiy,你可以先计算一个“滑动偏差”,并在你的前后价值中加入一种因子。因此,您可以动态缩小这个重音动作的间隔......请投票并或标记为已接受,如果有帮助,thx! – Shnugo

+0

我upvoted,但没有标记为答案呢:也许会有另一个。 –