1

我被困在下面的 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
对记录进行分组(即,相同 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. 同上
同样直到...第8条记录。
我尝试了各种分组和按查询分区,但被卡住了。任何帮助,将不胜感激。谢谢

4

2 回答 2

2

尝试

SELECT MAX(id), C1, C2, MAX([date])
FROM tbl
GROUP BY C1, C2, DATEADD(MINUTE, DATEDIFF(MINUTE,0,[date]) / 5 * 5, 0)
于 2013-10-23T16:27:57.890 回答
2

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

它将比较 m1、m2 和 m3 中的日期,并返回一个表checktimesagainsttimesWithinFiveMinutes如果它在上一条或下一条记录的五分钟内,则该表的列为 1。

然后我使用另一个公用表表达式来查询checktimesagainsttimes,两次。我第一次得到他们在五分钟内的团体的最大日期。然后,我将结果与checktimesagainsttimes不在五分钟内的结果合并。这些结果将返回到 maxdatesforwithin5minutes。

最后要做的是根据 c1、c2 和日期将这些结果加入到我的原始表中,以拉回实际的rowed.

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
于 2013-10-23T19:22:01.627 回答