1

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

これには自己結合が必要だと思います:

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 に答える
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 に答える