2017-01-09 1 views
0

Я не знаю, как название этот вопрос, но я изо всех сил .. У меня есть небольшой вызов с некоторых запросов с помощью SQL Server 2016.Выберите несколько групп строки из результата SQL Server

У меня есть таблица с много строк и все они имеют столбец временной метки. Основываясь на значении столбца Lane_0 (значение 0 или 1), мне нужно получить метку времени из столбца даты.

таблица выглядит следующим образом:

enter image description here

Группы строк помечены желтым цветом.

В основном таблица должна отслеживать, когда что-то включено или выключено. 1 = on и 0 = off. Мне нужно найти время, затраченное на выключение (значение 0) для каждой группы, а также самую старую и новейшую временную метку для этой группы. Группа представляет собой набор строк с 0 в Lane_0.

Из фотографии мне нужно будет получить Row_num 7, 8 и 9, а затем вычесть date_time в строке 9 из метки времени в строке 7, чтобы получить продолжительность. Наконец мне нужно выбрать date_time в ROW_NUM 7 и 9.

Результат должен выглядеть примерно так:

enter image description here

Последнее изображение показывает первую группу с тремя желтыми знаками. Мне нужен вид или SQL запрос, который может выбрать все действительные группы из таблицы 1.

+0

Благодаря GuidoG для исправления опечаток! Виноват! – Christian

ответ

1

Это стандартный трюк с последовательной группировкой:

DECLARE @t TABLE 
    (
     rn INT , 
     dt DATETIME , 
     ln INT 
    ) 
INSERT INTO @t 
VALUES (5, GETDATE(), 1), 
     (6, GETDATE(), 1), 
     (7, GETDATE(), 0), 
     (8, GETDATE(), 0), 
     (9, DATEADD(ss, 15, GETDATE()), 0), 
     (10, GETDATE(), 1), 
     (11, GETDATE(), 1), 
     (12, GETDATE(), 0), 
     (13, DATEADD(ss, 6, GETDATE()), 0), 
     (14, GETDATE(), 1); 


WITH cte 
      AS (SELECT * , 
         ROW_NUMBER() OVER (ORDER BY rn) 
         - ROW_NUMBER() OVER (ORDER BY ln, rn) r 
       FROM  @t 
      ) 
    SELECT MIN(dt) , 
      MAX(dt) , 
      DATEDIFF(ss, MIN(dt), MAX(dt)) 
    FROM cte 
    WHERE ln = 0 
    GROUP BY r 

Выход:

2017-01-09 15:47:31.560  2017-01-09 15:47:46.560 15 
2017-01-09 15:47:31.560  2017-01-09 15:47:37.560 6 
+0

Я бы никогда не догадался, что: D Великая помощь! Вы проверите это как можно скорее. Если вы можете предоставить мне хорошие статьи/блоги об этой проблеме, я был бы очень благодарен. – Christian

+1

https://www.simple-talk.com/sql/t-sql-programming/the-sql-of-gaps-and-islands-in-sequences/ –

1

Вы должны определить «Острова» в данных. Один метод использует разницу номеров строк:

select lane_no, min(datetime), max(datetime), count(*), 
     datediff(second, min(datetime), max(datetime)) as dur_second, 
     datediff(second, min(datetime), max(datetime))/60.0 as dur_minute 
from (select t.*, 
      row_number() over (partition by lane_no order by date_time) as seqnum_l, 
      row_number() over (order by date_time) as seqnum 
     from t 
    ) t 
where lane_no = 0 
group by lane_no, (seqnum - seqnum_l); 
+0

Немного другое решение того, что Giorgi Nakeuri просуществовал чуть ниже/выше. Будет ли результат таким же? – Christian

Смежные вопросы