自定义聚合函数或sql server中的等效函数

时间:2014-01-21 23:18:00

标签: sql sql-server sql-server-2012 aggregate-functions

SQL Server编程的新手,想知道我是否可以获得有关此查询的帮助。 说我有一个表LatencyInfo

DateTime              Latency
2014-01-21 00:00:00    12334
2014-01-21 00:00:00    56384
2014-01-20 00:00:00    1232
2014-01-20 00:00:00    4353
2014-01-19 00:00:00    434343

我的目标是在查询中找到每天的第95百分位延迟时间。所以,到目前为止,我能够为单个日期获得第95个百分点,但我坚持在日期汇总它。我无法使用PERCENTILE-CONT,因为我遇到的sql server版本不支持此查询。

select MIN(P.latency) 
from
  (select top 5 PERCENT S.latency as PerLatencyInfo 
    from
      (select convert(varchar(20), datetimefield, 1) as datefield
             ,latency
       from LatencyInfo
       where datetimefield >= '2014-01-21 00:00:00'
      ) as S
    order by S.latency DESC
  ) as P

任何帮助都非常感谢。我不能在这里尝试CLR聚合,因为我无法在服务器上安装.NET框架。

如果我不能使用自定义聚合函数,即使我可以获得任何其他等效逻辑的帮助,也会很棒。

使用Sql Server 11.0.9

2 个答案:

答案 0 :(得分:0)

在SQL Server 2005或更高版本中,您可以使用窗口函数并执行相同的操作:

select cast(datetime as date) as thedate, latency
from (select pli.*,
             row_number() over (partition by cast(datetime as date) order by latency) as seqnum,
             count(*) over (partition by cast(datetime as date)) as daycnt
      from PerLatencyInfo
     ) pli
where seqnum = 0.95 * daycnt;

seqnum只是枚举每天从最低延迟到最高延迟的值。值daycnt是当天的总数。第95百分位数在where子句中计算。

一些注释。

  • SQL Server 2005不支持cast( as date),但还有其他机制,例如convert()
  • 这不会在值之间进行插值。

答案 1 :(得分:0)

您应该查看 NTILE 窗口函数。

在下面的示例中,我使用了 NTILE(20),这将返回的行拆分为5%块,并为每个块分配1到20的数字。

SELECT   [DateTime], Latency
FROM    ( SELECT    [DateTime], 
        Latency, 
        NTILE(20) OVER ( PARTITION BY cast([DateTime] as date) ORDER BY Latency ASC) Top5
          FROM      latencyInfo
        ) x
WHERE   Top5 = 1

对DateTime 上的行进行分区,以便它在每个日期执行NTILE函数,按延迟升序排序(最小值位于顶部NTILE)。

然后,我所要做的就是选择最高百分位数的所有内容。 ( Top5 = 1