SQL按日期差异分组

SQL按日期差异分组,sql,sql-server,tsql,group-by,Sql,Sql Server,Tsql,Group By,我一直在写下面的sql查询。 我有一张桌子: id | C1 | C2 | date 1 | 1 | 1 | 1/10/2010 9:30:10 2 | 1 | 1 | 1/10/2010 9:31:10 3 | 1 | 1 | 1/10/2010 9:32:10 4 | 1 | 1 | 1/10/2010 9:37:10 5 | 1 | 2 | 1/10/2010 9:38:10 6 | 2 | 3 | 1/10/2010 9:39:10 7 | 2

我一直在写下面的sql查询。 我有一张桌子:

id | C1 | C2 | date

1  | 1  | 1  | 1/10/2010 9:30:10
2  | 1  | 1  | 1/10/2010 9:31:10
3  | 1  | 1  | 1/10/2010 9:32:10
4  | 1  | 1  | 1/10/2010 9:37:10
5  | 1  | 2  | 1/10/2010 9:38:10
6  | 2  | 3  | 1/10/2010 9:39:10
7  | 2  | 3  | 1/10/2010 9:45:10
8  | 2  | 3  | 1/10/2010 9:46:10
现在我想获取如下记录: 按日期差异分组记录5分钟的最晚日期以及相同C1和相同C2 i、 e.同一C1的每个C2的5分钟内的latset日期等记录。 我只希望输出为:

id | C1 | C2 | date

3  | 1  | 1  | 1/10/2010 9:32:10
4  | 1  | 1  | 1/10/2010 9:37:10
5  | 1  | 2  | 1/10/2010 9:38:10
6  | 2  | 3  | 1/10/2010 9:39:10
7  | 2  | 3  | 1/10/2010 9:46:10
说明: 1.前3条记录在5分钟内分组为同一C1和同一C2,第3条记录为这3条记录中最新的一条。 2.已获取第4条记录。这是同一个C1和C2在向后5分钟和向前5分钟内的唯一记录。 3.同上 同样地,直到。。。第八项记录。 我尝试了各种GROUPBY和partition by查询,但都失败了。任何帮助都将不胜感激。谢谢

试试看

SELECT MAX(id), C1, C2, MAX([date])
FROM tbl
GROUP BY C1, C2, DATEADD(MINUTE, DATEDIFF(MINUTE,0,[date]) / 5 * 5, 0)
试一试


可能有一个更简单的解决方案,但我使用了一个通用的表表达式checktimesagainsttimes来向前和向后检查针对同一个表连接的一条记录。如果我的数据在一个名为test3的表中,这将把数据看作是表m2,将它连接到它自己,将它前面的记录作为表m1,将它后面的记录作为表m3

它将比较m1、m2和m3中的日期,并返回一个表checktimesagainsttimes,该表中有一列infiveMinutes和1,如果该列在上一条或下一条记录的5分钟之内

然后我使用另一个公共表表达式查询checktimesagainsttimes,两次。我第一次得到五分钟内团体的最长日期。然后,我将结果与checktimesagainsttimes的结果合并,它们之间的间隔不在五分钟之内。这些结果将在5分钟内返回到MaxDatesFor

最后要做的事情是根据c1、c2和日期将这些结果合并回我的原始表,以提取实际的行


可能有一个更简单的解决方案,但我使用了一个通用的表表达式checktimesagainsttimes来向前和向后检查针对同一个表连接的一条记录。如果我的数据在一个名为test3的表中,这将把数据看作是表m2,将它连接到它自己,将它前面的记录作为表m1,将它后面的记录作为表m3

它将比较m1、m2和m3中的日期,并返回一个表checktimesagainsttimes,该表中有一列infiveMinutes和1,如果该列在上一条或下一条记录的5分钟之内

然后我使用另一个公共表表达式查询checktimesagainsttimes,两次。我第一次得到五分钟内团体的最长日期。然后,我将结果与checktimesagainsttimes的结果合并,它们之间的间隔不在五分钟之内。这些结果将在5分钟内返回到MaxDatesFor

最后要做的事情是根据c1、c2和日期将这些结果合并回我的原始表,以提取实际的行


5分钟之内是什么意思?前3个分组是否因为1和3之间的差异小于5分钟?还是1和2以及2和3之间的区别?或者是因为它们都在9:30和9:35之间?是的,因为它们都在9:30和9:35之间5分钟内。好的,分组9:30也是这样,但是在第一种情况下,9:30的一行在9:31与另一行分组,而在第二种情况下,不是,因为它们将在9:29与一行分组。你说的5分钟内是什么意思?前3个分组是否因为1和3之间的差异小于5分钟?还是1和2以及2和3之间的区别?或者是因为它们都在9:30和9:35之间?是的,因为它们都在9:30和9:35之间,在5分钟内。好的,分组9:30也是这样,但在第一种情况下,9:30的一行在9:31与另一行分组,而在第二种情况下不是,因为它将在9:29与一行分组。
WITH    checktimesagainsttimes
          AS ( SELECT   m2.id AS id2 ,
                        m1.id AS id1 ,
                        m3.id AS id3 ,
                        m2.date ,
                        m2.c1 ,
                        m2.c2 ,
                        CASE WHEN ( DATEADD(mi, 5, m2.date) > m3.date
                                    AND m2.date < m3.date
                                  )
                                  OR ( DATEADD(mi, -5, m2.date) < m1.date
                                       AND m2.date > m1.date
                                     ) THEN 1
                             ELSE 0
                        END AS WithinFiveMinutes
               FROM     test3 m2
                        LEFT OUTER JOIN test3 m1 ON m2.c1 = m1.c1
                                                    AND m2.c2 = m1.c2
                                                    AND ( m2.id = m1.id
                                                          + 1 )
                        LEFT OUTER JOIN test3 m3 ON m2.c1 = m3.c1
                                                    AND m2.c2 = m3.c2
                                                    AND ( m2.id = m3.id
                                                          - 1 )
             ),
        maxdatesforwithin5minutes
          AS ( SELECT   c1 ,
                        c2 ,
                        MAX(date) AS date
               FROM     checktimesagainsttimes
               WHERE    WithinFiveMinutes = 1
               GROUP BY c1 ,
                        c2 ,
                        withinFiveMinutes
               UNION
               SELECT   c1 ,
                        c2 ,
                        date
               FROM     checktimesagainsttimes
               WHERE    WithinFiveMinutes = 0
             )
    SELECT  t.id ,
            t.c1 ,
            t.c2 ,
            t.date
    FROM    maxdatesforwithin5minutes m
            INNER JOIN test3 t ON m.c1 = t.c1
                                  AND m.c2 = t.c2
                                  AND m.date = t.date