【问题标题】:SQL group by date differenceSQL 按日期差异分组
【发布时间】:2013-10-24 09:18:43
【问题描述】:

我被困在下面的 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 条记录。
我尝试了各种分组和查询分区,但被卡住了。任何帮助,将不胜感激。谢谢你

【问题讨论】:

  • “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 与另一行分组)。

标签: sql sql-server tsql group-by


【解决方案1】:

试试

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

【讨论】:

    【解决方案2】:

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

    它将比较 m1、m2 和 m3 中的日期并返回一个表 checktimesagainsttimes,如果它在上一条或下一条记录的五分钟内,则该表的列 WithinFiveMinutes 为 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-05-05
      • 1970-01-01
      • 2019-07-19
      • 2021-07-24
      • 2021-09-04
      • 1970-01-01
      • 2020-09-08
      • 2015-05-31
      相关资源
      最近更新 更多