Интервалы группировки C # SQL с использованием DateDiff? - PullRequest
1 голос
/ 24 ноября 2011

У меня есть следующая таблица:

RowA     RowB    date_time            RowD  
-------  ------- -------------------  -------
ValueA1  ValueB1 01.01.2001 16:23:01  ValueD1  
ValueA2  ValueB2 01.01.2001 16:23:06  ValueD2  
ValueA3  ValueB3 01.01.2001 16:23:11  ValueD3  
ValueA4  ValueB4 03.01.2001 12:23:01  ValueD4  
ValueA5  ValueB5 03.01.2001 16:23:06  ValueD5  
ValueA6  ValueB6 03.01.2001 16:23:11  ValueD6  
ValueA7  ValueB7 03.01.2001 16:23:16  ValueD7  

Таблица продолжается примерно 50k строк.Я хотел бы сгруппировать эти значения, взятые с интервалом 5 с, в качестве попытки1, попытки 2 ... и т. Д. Мне также нужно сделать группы попыток 1, попытки 2 ... и т. Д. Доступными, чтобы я мог включить или отключить их видимость вDataGridview с использованием флажков, например.

Я очень плохо знаком с SQL и уже два дня ищу решение, пробовал GROUP BY, DATEDIFF и DATEADD, но большинство решенийЯ обнаружил, что только подсчитывал или суммировал значения групп.

Решение, использующее RowFilter, было бы потрясающим, но строка sql тоже была бы очень признательна.

EDIT

Извините, я не мог ответить раньше.Оба предложенных вами результата - не то, что я искал, и я не уверен, что результаты, которые я желаю, могут быть решены с помощью SQL сейчас.Результирующая таблица, которую я хочу получить, должна выглядеть следующим образом (я добавил некоторые значения, потому что понял, что те, которые я использовал до сих пор, вероятно, не дают четкого представления о том, что я хотел):

Attempt  RowA    RowB    date_time           RowD  
-------- ------- ------- ------------------- -------
attempt1 ValueA1 ValueB1 01.01.2001 16:23:01 ValueD1   |
attempt1 ValueA2 ValueB2 01.01.2001 16:23:06 ValueD2   | attempt1 since 5s difference (over 3 lines)
attempt1 ValueA3 ValueB3 01.01.2001 16:23:11 ValueD3   |
attempt2 ValueA4 ValueB4 03.01.2001 12:23:01 ValueD4  -> new and one line only attempt (difference bigger than 5s)
attempt3 ValueA5 ValueB5 03.01.2001 16:23:06 ValueD5   |
attempt3 ValueA6 ValueB6 03.01.2001 16:23:11 ValueD6   | attempt3 since 5s difference (over 3 lines)
attempt3 ValueA7 ValueB7 03.01.2001 16:23:16 ValueD7   |
attempt4 ValueA8 ValueB8 04.01.2001 02:16:53 ValueD8   - attempt4 since 5s difference...
attempt4 ValueA9 ValueB9 04.01.2001 02:16:58 ValueD9   - (2 lines)

1 Ответ

1 голос
/ 24 ноября 2011

Я не уверен, что это можно решить, используя только «нормальный» SQL (без некоторых итеративных функций, таких как cursors ).

Если вы можете быть уверены, что каждая попытка начинается в полные минуты и длится менее 60 секунд, тогда этот простой подход может сработать:

  select convert(smalldatetime, date_time), 
         min(RowA), min(RowB), min(RowD), 
         max(RowA), max(RowB), max(RowD)
  from   YourTableName
  group by convert(smalldatetime, date_time)

Но это работает только потому, что smalldatetime удаляет часть секунд вашего поля date_time.

Кроме того, в моем примере я предполагаю, что RowA, B и D содержат некоторые значения, которые являются прогрессивными, что я считаю моим неверным предположением.

Возможно, вам придется написать здесь несколько подзапросов:

Обновление

В этом запросе должны быть перечислены все попытки запуска:

 select t1.*
 from   <YourTableName> t1
 where not exists(
     select * 
     from   <YourTableName> t2
     where  t2.date_time >= dateadd(s, -5, t1.date_time) 
     and    t2.date_time < t1.date_time 
 )

Результат для данных в вашем примере:

RowA    RowB    date_time               RowD
------- ------- ----------------------- -------   
ValueA1 ValueB1 2001-01-01 16:23:01.000 ValueD1
ValueA4 ValueB4 2001-03-01 12:23:01.000 ValueD4
ValueA5 ValueB5 2001-03-01 16:23:06.000 ValueD5

Я не знаю, нужен ли вам также последний ряд каждой попытки в строках вашей сетки (в той же строке). Это усложнит ситуацию.

Обновление 2:

Если вы используете SQL Server 2005 (или новее), вы можете использовать общие табличные выражения, например, этот запрос, который дает начальную и конечную строку в одну строку:

 with start_rows as (
     select start.* 
     from   <YourTablenName> start
     where  not exists(
       select * 
       from   <YourTableName> start2
       where  start2.date_time >= dateadd(s, -5, start.date_time) 
       and    start2.date_time < start.date_time 
     )
 ),
 stop_rows as (   
     select stop.*
     from   <YourTablenName> stop
     where  not exists(
        select * 
        from <YourTableName> stop2
        where stop2.date_time <= dateadd(s, 5, stop.date_time) 
        and   stop2.date_time > stop.date_time 
     )
 ) 
 select start_rows.*, stop_rows.*
 from   start_rows, stop_rows
 where start_rows.date_time <= stop_rows.date_time
 and    not exists(
    select * from stop_rows sr2
    where sr2.date_time < stop_rows.date_time
    and sr2.date_time >= start_rows.date_time
 )
 order by start_rows.date_time

Результат в этом случае:

ValueA1 ValueB1 2001-01-01 16:23:01.000 ValueD1 ValueA3 ValueB3 2001-01-01 16:23:11.000 ValueD3
ValueA4 ValueB4 2001-03-01 12:23:01.000 ValueD4 ValueA4 ValueB4 2001-03-01 12:23:01.000 ValueD4
ValueA5 ValueB5 2001-03-01 16:23:06.000 ValueD5 ValueA7 ValueB7 2001-03-01 16:23:16.000 ValueD7
...