Group By基于SQL Server中10秒时间间隔的记录

时间:2016-07-19 09:58:09

标签: sql sql-server datetime dense-rank partition-by

要求是基于10秒的时间间隔对表的组记录。给表

 Id      DateTime            Rank
 1     2011-09-27 18:36:15      1
 2     2011-09-27 18:36:15      1
 3     2011-09-27 18:36:19      1
 4     2011-09-27 18:36:23      1
 5     2011-09-27 18:36:26      1
 6     2011-09-27 18:36:30      1
 7     2011-09-27 18:36:32      1
 8     2011-09-27 18:36:14      2
 9     2011-09-27 18:36:16      2
 10    2011-09-27 18:36:35      2

组应该是这样的

 Id      DateTime            Rank    GroupRank
 1     2011-09-27 18:36:15      1         1
 2     2011-09-27 18:36:15      1         1
 3     2011-09-27 18:36:19      1         1
 4     2011-09-27 18:36:23      1         1
 5     2011-09-27 18:36:26      1         2
 6     2011-09-27 18:36:30      1         2
 7     2011-09-27 18:36:32      1         2
 8     2011-09-27 18:36:14      2         3
 9     2011-09-27 18:36:16      2         3
 10    2011-09-27 18:36:35      2         4

对于等级1最短时间是18:36:15,并且基于18:36:15到18:36:24之间的所有记录都应该在一个组中,依此类推。

我希望GroupRank在同一个表中。所以它会与dense_Rank()Over子句有关。任何人都可以帮我在SQL中编写查询。

1 个答案:

答案 0 :(得分:0)

你需要分两步完成这个步骤,第一步是将每个记录分成10个秒组,方法是从每个等级的最小时间得到秒数,除以10,然后将其四舍五入到最接近的整数。

SELECT  *,
        SecondGroup = FLOOR(DATEDIFF(SECOND, 
                                    MIN([DateTime]) OVER(PARTITION BY [Rank]), 
                                    [DateTime]) / 10.0)
FROM    #T;

给出了:

Id  DateTime                    Rank    SecondGroup
---------------------------------------------------
1   2011-09-27 18:36:15.000     1       0
2   2011-09-27 18:36:15.000     1       0
3   2011-09-27 18:36:19.000     1       0
4   2011-09-27 18:36:23.000     1       0
5   2011-09-27 18:36:26.000     1       1
6   2011-09-27 18:36:30.000     1       1
7   2011-09-27 18:36:32.000     1       1
8   2011-09-27 18:36:14.000     2       0
9   2011-09-27 18:36:16.000     2       0
10  2011-09-27 18:36:35.000     2       2

然后,您可以DENSE_RANKRank进行SecondGroup排序:

SELECT  Id, [DateTime], [Rank],
        GroupRank = DENSE_RANK() OVER(ORDER BY [Rank], SecondGroup)
FROM    (   SELECT  *,
                    SecondGroup = FLOOR(DATEDIFF(SECOND, 
                                                MIN([DateTime]) OVER(PARTITION BY [Rank]), 
                                                [DateTime]) / 10.0)
            FROM    #T
        ) AS t;

这可以提供您想要的输出。

示例数据

CREATE TABLE #T (Id INT, [DateTime] DATETIME, [Rank] INT);

INSERT #T (Id, [DateTime], [Rank])
VALUES
    (1, '2011-09-27 18:36:15', 1),
    (2, '2011-09-27 18:36:15', 1),
    (3, '2011-09-27 18:36:19', 1),
    (4, '2011-09-27 18:36:23', 1),
    (5, '2011-09-27 18:36:26', 1),
    (6, '2011-09-27 18:36:30', 1),
    (7, '2011-09-27 18:36:32', 1),
    (8, '2011-09-27 18:36:14', 2),
    (9, '2011-09-27 18:36:16', 2),
    (10, '2011-09-27 18:36:35', 2);