2013-12-04 3 views
2

Я пытаюсь выяснить, как я могу пометить уникальные (то, что я называю) блоки (или сегменты, если вы захотите), которые имеют начальные и конечные последовательные строки «Поездка», упорядоченные по «эпоха» использует один и тот же «код». В этом случае группа «trip», «code» не будет работать, так как мне нужно измерить длительность «кода», остается постоянной для поездки. Я попытался использовать CTE, но я не смог разбить данные таким образом, чтобы он дал желаемый результат, показанный ниже. Номер блока, который я показал, может быть любым значением, только до тех пор, пока он уникален, поэтому он маркирует последовательные вхождения одного и того же «кода» в поездке в порядке «эпохи».Создание блоков в CTE-SQL Server

Любые идеи?

declare @data table (id int, trip int, code int NULL, epoch int, value1 int, value2 int); 
insert into @data (id, trip, code, epoch, value1, value2) 
values 
(1, 1, null, 31631613, 0, 0), 
(2, 2, 1, 31631614, 10, 40), 
(3, 1, 1, 31631616, 10, 60), 
(4, 1, 1, 31631617, 40, 60), 
(5, 2, 1, 31631617, 23, 40), 
(6, 2, 2, 31631620, 27, 40), 
(7, 2, 2, 31631629, 23, 40), 
(9, 1, 1, 31631618, 39, 60), 
(10, 1, null, 31631621, 38, 60), 
(12, 1, null, 31631625, 37, 60), 
(15, 1, null, 31631627, 35, 60), 
(19, 1, 1, 31631630, 39, 60), 
(20, 1, 1, 31631632, 40, 60), 
(21, 2, 1, 31631629, 23, 40); 


block id trip code  epoch value1 value2 
1  1 1  NULL 31631613 0 0 
2  2 2  1  31631614 10 40 
2  5 2  1  31631617 23 40 
3  3 1  1  31631616 10 60 
3  4 1  1  31631617 40 60 
3  9 1  1  31631618 39 60 
4  6 2  2  31631620 27 40 
4  7 2  2  31631629 23 40 
5  10 1  NULL 31631621 38 60 
5  12 1  NULL 31631625 37 60 
5  15 1  NULL 31631627 35 60 
6  19 1  1  31631630 39 60 
6  20 1  1  31631632 40 60 
7  21 2  1  31631629 23 40 
+0

Какая версия SQL Server? – dazedandconfused

+0

Кроме того, почему не последняя строка в вашем выводе (trip = 2, code = 1, epoch = 31631629) четвертая строка ... вверх с другой поездкой = 2, код = 1 запись? Тот же вопрос для поездки = 1, код = 1 строка. – dazedandconfused

+0

SQL 2008 R2 & Thanks ошеломлен забрать в моих случайных данных, которые я пробил поздно ночью. Я также заметил это, когда через день я вернулся к проблеме. Во всяком случае, я сделал какой-то прогресс, который поможет. – user3064548

ответ

0

Хорошо, это далеко от совершенства любых средств, но это стартер, что, по крайней мере определяет начало и конец смежного блока, где «код» остался тем же для поездки. Ради хотя бы того, чтобы внести что-то, я отправлю то, что я придумал. Если я когда-нибудь найду время на правильную работу, я отправлю его.

declare @minint int; set @minint = -2147483648; 
declare @maxint int; set @maxint = 2147483647; 
declare @id_data table (pk int IDENTITY(1,1), id int, trip int, code int NULL, epoch int, value1 int, value2 int); 

insert into @id_data VALUES(@minint, @minint, @minint, @minint, @minint, @minint); 
insert into @id_data 
SELECT id, trip, coalesce(code,0), epoch, value1, value2 
    FROM @data 
order by trip, epoch, code; 
insert into @id_data VALUES(@maxint, @maxint, @maxint, @maxint, @maxint, @maxint); 

WITH CTE as 
(
SELECT pk, id, trip, code, epoch, value1, value2, ROW_NUMBER() OVER (PARTITION BY trip ORDER BY epoch) as row_num 
FROM @id_data 
) 
SELECT B.*, A.code, C.min_next_code 
FROM CTE A 
INNER JOIN CTE B ON (B.pk = A.pk + 1) AND (A.code != B.code) -- SELECTS THE RECORDS  THAT START A NEW GROUP 
OUTER APPLY (
SELECT min_next_code = MIN(pk) - 1 -- LOCATION OF NEXT GROUP 
FROM CTE 
WHERE pk > B.pk AND (trip = B.trip) AND (code != B.code) 
) C 
WHERE B.id < @maxint 
0

Вы не обновили ожидаемый результат, так что я до сих пор не 100% уверен, что это то, что вы хотите, но дайте ему попробовать ...

SELECT 
    DENSE_RANK() OVER (ORDER BY trip, code), 
    * 
FROM 
    @data 
ORDER BY 
    trip, code, epoch 
+0

Спасибо за вашу помощь, я думаю, что некоторые более подробные пояснения в порядке. Какова конечная цель - измерить разницу в эпохе, когда начинается код поездки, и код отключения изменяет код/​​конец поездки. Подумайте о том, что «код» выглядит как уровень тревоги, когда бизнес-KPI может обеспечить одинаковый сигнал тревоги, например, 30 секунд, но поездка может продолжаться и поднимать эту тревогу, но она рассматривается как новый случай для Измерение KPI. – user3064548

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