我的SQL数据库中有以下表格,需要按照5分钟的最大值对其进行分组。
+------+--------+------------------+
| Path | Sample | DateTime |
+------+--------+------------------+
| Srv1 | 0.5 | 2014-07-04 10:48 |
| Srv1 | 0.7 | 2014-07-04 10:50 |
| Srv1 | 0.9 | 2014-07-04 10:52 |
| Srv1 | 0.6 | 2014-07-04 10:54 |
| Srv2 | 8.2 | 2014-07-04 10:48 |
| Srv2 | 7.4 | 2014-07-04 10:50 |
| Srv2 | 10.9 | 2014-07-04 10:52 |
| Srv2 | 9.9 | 2014-07-04 10:54 |
| Srv3 | 7.8 | 2014-07-04 10:48 |
| Srv3 | 1.3 | 2014-07-04 10:50 |
| Srv3 | 5.7 | 2014-07-04 10:52 |
| Srv3 | 2.4 | 2014-07-04 10:54 |
| Srv4 | 4.2 | 2014-07-04 10:47 |
| Srv4 | 3.8 | 2014-07-04 10:49 |
| Srv4 | 5.4 | 2014-07-04 10:51 |
| Srv4 | 2.4 | 2014-07-04 10:53 |
| Srv5 | 1.6 | 2014-07-04 10:48 |
| Srv5 | 1.3 | 2014-07-04 10:50 |
| Srv5 | 1.6 | 2014-07-04 10:52 |
| Srv5 | 1.3 | 2014-07-04 10:54 |
+------+--------+------------------+
下表是我的目标:
+------+--------+------------------+
| Path | Sample | DateTime |
+------+--------+------------------+
| Srv1 | 0.5 | 2014-07-04 10:45 |
| Srv1 | 0.9 | 2014-07-04 10:50 |
| Srv2 | 8.2 | 2014-07-04 10:45 |
| Srv2 | 10.9 | 2014-07-04 10:50 |
| Srv3 | 7.8 | 2014-07-04 10:45 |
| Srv3 | 5.7 | 2014-07-04 10:50 |
| Srv4 | 6.8 | 2014-07-04 10:45 |
| Srv4 | 5.4 | 2014-07-04 10:50 |
| Srv5 | 1.6 | 2014-07-04 10:45 |
| Srv5 | 1.6 | 2014-07-04 10:50 |
+------+--------+------------------+
我尝试了以下代码,但它并没有发出预期的结果。 GROUP BY me.Path, pd.DateTime, DATEPART(mi, pd.DateTime) % 10
我的整个SQL是:
SELECT TOP (100) PERCENT me.Path, MAX(pd.SampleValue) AS Sample, pd.DateTime
FROM Perf.vPerfRaw AS pd
INNER JOIN dbo.vPerformanceRuleInstance AS pri ON pri.PerformanceRuleInstanceRowId = pd.PerformanceRuleInstanceRowId
INNER JOIN dbo.vPerformanceRule AS pr ON pr.RuleRowId = pri.RuleRowId
INNER JOIN dbo.vManagedEntity AS me ON me.ManagedEntityRowId = pd.ManagedEntityRowId
INNER JOIN dbo.vRule AS vr ON vr.RuleRowId = pri.RuleRowId
INNER JOIN OperationsManager.dbo.RelationshipGenericView AS rgv ON rgv.TargetObjectDisplayName = me.Path
WHERE (pr.CounterName = '% Processor Time')
AND (vr.RuleDefaultName = 'Processor % Processor Time Total 2003'
OR vr.RuleDefaultName = 'Processor % Processor Time Total Windows Server 2008'
OR vr.RuleDefaultName = 'Processor Information % Processor Time Total Windows Server 2008 R2'
OR vr.RuleDefaultName = 'Processor Information % Processor Time Total Windows Server 2012'
OR vr.RuleDefaultName = 'Processor Information % Processor Time Total Windows Server 2012 R2')
AND (rgv.SourceObjectDisplayName = 'SVM')
GROUP BY me.Path, pd.DateTime, DATEPART(mi, pd.DateTime) % 10
ORDER BY me.Path
答案 0 :(得分:1)
您将pd.DateTime
放在所选列和group by子句中,因此您实际上并未执行任何聚合。
有很多方法可以做到这一点,有些方法比其他方法更好,具体取决于您的数据,但请尝试以下方法:
SELECT TOP (100) PERCENT
me.Path,
MAX(pd.SampleValue) AS Sample,
DATEADD(MI, -(DATEPART(MI, pd.DateTime) % 5), pd.DateTime) AS PeriodStart
FROM ...
WHERE ...
GROUP BY me.Path, DATEADD(MI, -(DATEPART(MI, pd.DateTime) % 5), pd.DateTime)
ORDER BY me.Path
请注意,这仅在日期时间值中的秒数始终为0时才有效。否则,您需要一个额外的DATEADD
来抵消它们。
答案 1 :(得分:0)
%
是余数运算符。你想要整数除法。
select [path], MAX(sample),
convert(time,dateadd(minute,convert(int,(CONVERT(decimal(9,4), datetime) % 1)/0.003472)*5,0))
from yourdata
GROUP BY Path, convert(time,dateadd(minute,convert(int,(CONVERT(decimal(9,4), datetime) % 1)/0.003472)*5,0))
答案 2 :(得分:0)
试试这个
SELECT Path, MAX(Sample), DATEADD(MINUTE, (CASE WHEN DATEPART(MINUTE, Created)%5 BETWEEN 1 AND 2 THEN 0 ELSE 5 END)-(DATEPART(MINUTE, Created))%5, Created) AS NewDate
FROM ...
GROUP BY Path, DATEADD(MINUTE, (CASE WHEN DATEPART(MINUTE, Created)%5 BETWEEN 1 AND 2 THEN 0 ELSE 5 END)-(DATEPART(MINUTE, Created))%5, Created)
ORDER BY Path
答案 3 :(得分:0)
现有答案的一个问题是,由于在“源”列上使用了函数,因此没有人能够使用索引。您可以通过定义内联范围查询表的简单权宜来获得更好的性能,就像递归CTE一样。像这样:
WITH Time_Slice AS (SELECT startedAt, endedBy
FROM (VALUES(CAST('20140704' AS DATETIME2),
DATEADD(minute, 5, CAST('20140704' AS DATETIME2)))) a(startedAt, endedBy)
UNION ALL
SELECT endedBy, DATEADD(minute, 5, endedBy)
FROM Time_Slice
WHERE endedBy < DATEADD(day, 1, CAST('20140704' AS DATETIME2)))
SELECT *
FROM Time_Slice
OPTION(MAXRECURSION 0)
显然,这需要在特定范围内生成 - 如果您只选择给定范围的结果,则可以将其用作开始/结束值;否则,看起来在起始部分中获取MIN()
值并运行到当前时间。
然后,您可以将其作为常规表引用,如下所示:
SELECT TOP (100) PERCENT me.Path, MAX(pd.SampleValue) AS Sample, ts.startedAt
FROM Perf.vPerfRaw AS pd
INNER JOIN dbo.vManagedEntity AS me ON me.ManagedEntityRowId = pd.ManagedEntityRowId
INNER JOIN Time_Slice AS ts ON pd.DateTime >= ts.startedAt AND pd.DateTime < ts.endedBy
GROUP BY me.Path, ts.startedAt
ORDER BY me.Path