我正在使用MSSQL 2000数据库,其中包含为环境中的所有服务器收集的大量Windows perfmon数据。我正在使用SSRS 2005构建自定义报告图表,以便随时间显示指标。
如果我想查看,比如上个月,大量的数据点会在X轴上创建一个丑陋的报告,标签不可读。我希望将数据汇总时间减少到 n 数据点,以便给出分组时间跨度的平均值。
我尝试使用花哨的GROUP BY子句构建查询,但是无法构建执行的东西。我认为这应该是SQL的常见任务,但我没有在网上找到任何答案。
表结构基本如下所示。这实际上是MOM 2005 OnePoint数据库,但我认为该应用程序无关紧要。
CREATE TABLE PerfTable (
[time] datetime,
value float,
Server nvarchar(356),
ObjectName nvarchar(225),
CounterName nvarchar(225),
InstanceName nvarchar(225),
Scale float
);
答案 0 :(得分:1)
可能值得构建一个View以查看数月的数据,并使用SQL背后的数据来减少数据量。
然后您可以从该视图运行报告。
此外,您可能需要了解所涉及的表格结构以及您目前用于获取结果的SQL。
答案 1 :(得分:0)
您真的需要减少从SQL返回的记录数量,还是只减少图表呈现的数据?
从SQL获取所有值可能更容易,然后将数据按到稍后更有用的东西上。更改查询将减少网络使用量,因为将发送更少的数据,但如果这不是一个问题,那么查询可能不是最好的地方。
答案 2 :(得分:0)
您可以使用DATEPART功能获取按特定日期,小时或分钟(或其他几个)过滤的数据块。您应该能够按这些分组并获得所需的平均值/总量。
好的,这是获得n个聚合的解决方案(就每个时间段的数据而言):
declare @points as int
declare @start as float
declare @period as float
set @points = 20
select
@start=cast(min(time) as float),
@period=cast(max(time)-min(time) as float)
from perftable
select avg(value),
round((cast(time as float)-@start)/(@period/@points),0,1)
from perftable
group by
round((cast(time as float)-@start)/(@period/@points),0,1)
@points变量是您想要获得的数字od聚合。 @start是报告中浮动的第一条记录的时间 @period是报告中开始和结束日期之间的差异
其余几乎是将日期线性缩放到范围[0; @points],将结果截断为整数并按截断结果进行分组。
答案 3 :(得分:0)
假设我们希望在该范围内拥有3倍的时间和“平均值”。
首先我们确定期间..开始 - 结束,开始 - 结束,开始 - 结束等 这可以在你自己的代码中完成,所以我使用参数。
在此示例中,我们还按“服务器”进行分组,但您可以添加额外的列或将其删除。
DECLARE @startdate1 as DateTime
DECLARE @enddate1 as DateTime
DECLARE @startdate2 as DateTime
DECLARE @enddate2 as DateTime
DECLARE @startdate3 as DateTime
DECLARE @enddate3 as DateTime
SELECT
CASE WHEN time >= @startdate1 AND time < @enddate1 THEN 'PERIOD1'
ELSE CASE WHEN time >= @startdate2 AND time < @enddate2 THEN 'PERIOD2'
ELSE CASE WHEN time >= @startdate3 AND time < @enddate3 THEN 'PERIOD3'
END
END
END as Period,
AVG(p.[value]),
p.[Server]
FROM PerfTable p
GROUP BY
CASE WHEN time >= @startdate1 AND time < @enddate1 THEN 'PERIOD1'
ELSE CASE WHEN time >= @startdate2 AND time < @enddate2 THEN 'PERIOD2'
ELSE CASE WHEN time >= @startdate3 AND time < @enddate3 THEN 'PERIOD3'
END
END
END,
p.[Server]
答案 4 :(得分:0)
我的解决方案与我的要求密切相关。如果我想按时间单位分组,那很简单:
按小时分组:
select
dateadd(hh, datediff(hh, '1970-01-01', [time]), '1970-01-01'),
Server, ObjectName, CounterName, InstanceName, avg(value)
from PerfTable
group by
dateadd(hh, datediff(hh, '1970-01-01', [time]), '1970-01-01'),
ComputerName, ObjectName, CounterName, InstanceName
order by
dateadd(hh, datediff(hh, '1970-01-01', [time]), '1970-01-01') desc,
ObjectName, CounterName, InstanceName, ComputerName
这并不能解决缩小到 n 数据点的需要。