SQL按时间分组

SQL按时间分组,sql,sql-server,group-by,Sql,Sql Server,Group By,我的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:

我的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 |
+------+--------+------------------+
我尝试了下面的代码,但没有得到预期的结果<代码>按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

%
是余数运算符。你想要整数除法

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)) 

您将
pd.DateTime
放在所选列和GROUPBY子句中,因此实际上没有执行任何聚合

有很多方法可以做到这一点,根据您的数据,有些方法比其他方法更好,但请尝试以下方法:

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
请注意,只有当datetime值中的秒数始终为0时,这才有效。您需要一个附加的
DATEADD
来抵消它们。

试试这个

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

现有答案的一个问题是,由于在“源”列上使用了函数,因此没有人能够使用索引。通过定义一个内联范围查询表(如递归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)
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

如果您给出一个表和完整查询的严格模式,这会有所帮助,因为“示例”中的名称与您尝试的代码中的列不匹配(这似乎还涉及两个表
me
pd
),所以我不确定是否理解您想要/尝试的内容。