1

我有一个表格,其中一列是日期:

+----------+---------------------+
|       id |                date |  
+----------+---------------------+
|        5 | 2012-12-10 10:12:37 |        
+----------+---------------------+
|        4 | 2012-12-10 09:09:55 |        
+----------+---------------------+
|        3 | 2012-12-09 21:12:35 |        
+----------+---------------------+
|        2 | 2012-12-09 20:15:07 |        
+----------+---------------------+
|        1 | 2012-12-09 20:01:42 |        
+----------+---------------------+

我需要的是计算彼此相隔 3 小时的行数。在此示例中,我想将上排与第 2 行连接起来,将第 3 行与第 4 行和第 5 行连接起来。所以我的输出应该是这样的:

+----------+---------------------+---------+
|       id |                date |   count | 
+----------+---------------------+---------+
|        5 | 2012-12-10 10:12:37 |       2 |
+----------+---------------------+---------+
|        3 | 2012-12-09 21:12:35 |       3 |
+----------+---------------------+---------+

我怎么能这样做?

4

2 回答 2

0

我不确定如何使用 My SQL 执行此操作,但我能够在 SQL Server 2005 中构建一组查询,这些查询将提供预期的结果。这是工作示例,它非常复杂并且可能过于复杂,但这就是我能够获得所需结果的方式:

WITH BaseData AS
(
    SELECT 5 AS ID, '2012-12-10 10:12:37' AS Date
    UNION ALL  
    SELECT 4 AS ID, '2012-12-10 09:09:55' AS Date
    UNION ALL  
    SELECT 3 AS ID, '2012-12-09 21:12:35' AS Date
    UNION ALL  
    SELECT 2 AS ID, '2012-12-09 20:15:07' AS Date
    UNION ALL  
    SELECT 1 AS ID, '2012-12-09 20:01:42' AS Date
),
BaseDataWithRowNum AS
(
    SELECT ID,DATE, ROW_NUMBER() OVER (ORDER BY Date DESC) AS RowNum
      FROM BaseData
),
InterRelatedDates AS
(
    SELECT B1.RowNum AS RowNum1,B2.RowNum AS RowNum2 
      FROM BaseDataWithRowNum B1
     INNER JOIN BaseDataWithRowNum B2
        ON B1.Date BETWEEN B2.Date AND DATEADD(hh,3,B2.Date)
       AND B1.RowNum < B2.RowNum 
       AND B1.ID != B2.ID
),
InterRelatedDatesWithinMultipleGroups AS
(
    SELECT G1.RowNum1,G2.RowNum2
      FROM InterRelatedDates G1
      LEFT JOIN InterRelatedDates G2
        ON G1.RowNum2 = G2.RowNum2
       AND G1.RowNum1 != G2.RowNum1
 )


SELECT BN.ID,
       BN.Date, 
       CountExcludingOriginalGrouppingRecord +1 AS C
  FROM
      (
        SELECT RowNum1 AS RowNum,COUNT(1) AS CountExcludingOriginalGrouppingRecord
          FROM
              (
                -- If a row was used in only one group then it is ok. use as it is
                SELECT D1.RowNum1
                  FROM InterRelatedDatesWithinMultipleGroups AS D1
                 WHERE D1.RowNum2 IS NULL

                UNION ALL

                -- In case a row was selected in two groups, choose the one with higher date
                SELECT Min(D1.RowNum1)
                  FROM InterRelatedDatesWithinMultipleGroups AS D1
                 WHERE D1.RowNum2 IS NOT NULL
                 GROUP BY D1.RowNum2
              ) T
        GROUP BY RowNum1
      ) T2
INNER JOIN BaseDataWithRowNum BN
   ON BN.RowNum = T2.RowNum
于 2013-02-11T22:12:07.170 回答
0

我认为你需要一个自我加入:

select t.id, t.date, COUNT(t2.id)
from t left outer join
     t t2
     on t.date between t2.date - interval 3 hour and t2.date + interval 3 hour
group by t.id, t.date

(这是未经测试的代码,因此可能存在语法错误。)

如果您尝试将所有内容分成 3 小时间隔,您可以执行以下操作:

select max(t.date), t.id, count(*)
from (select t.*,
             (date(date)*100 + floor(hour(date)/3)*3) as interval
      from t
     ) t
group by interval
于 2013-02-11T19:58:25.523 回答