из нее надо выбрать только те строки, где меняется Param1 или Param2, они отмечены <<. База — MS SQL 2005/2008. Подскажите ключевые слова как это пооптимальнее изобразить.
Здравствуйте, Odi$$ey, Вы писали:
OE>из нее надо выбрать только те строки, где меняется Param1 или Param2, они отмечены <<. База — MS SQL 2005/2008. Подскажите ключевые слова как это пооптимальнее изобразить.
Здравствуйте, Odi$$ey, Вы писали:
OE>из нее надо выбрать только те строки, где меняется Param1 или Param2, они отмечены <<. База — MS SQL 2005/2008. Подскажите ключевые слова как это пооптимальнее изобразить.
1) Написать multi-column aggregate — но тут надо думать.
2) покопаться с ranking functions (кмк бесперспективно)
3) table-valued function с курсором и фильтрацией внутри (увы, харкод структуры данных)
Или, если уникальность времени гарантируется, как-то так (синтаксис 2008го):
DECLARE @Tbl TABLE (ID int, P1 int NOT NULL, P2 int NOT NULL)
INSERT @Tbl (ID, P1, P2) VALUES
(1,1,1),
(4,1,1),
(7,0,1),
(8,0,1),
(9,1,2),
(10,1,1);
SELECT T1.* FROM @Tbl T1
WHERE
EXISTS (
SELECT T2.*
FROM @Tbl T2
WHERE T2.ID < T1.ID
AND (T2.P1 <> T1.P1 OR T2.P2 <> T1.P2)
-- гарантируем, что в T2 - только строка перед T1AND NOT EXISTS (SELECT T3.* FROM @Tbl T3 WHERE T3.ID < T1.ID AND T3.ID > T2.ID)
)
-- + первая строкаOR NOT EXISTS (SELECT T4.* FROM @Tbl T4 WHERE T4.ID < T1.ID);
declare @t TABLE (TimeStamp datetime,Param1 int ,Param2 int)
insert into @t
select '10:21:21', 0, 0 union all
select '10:21:22', 0, 0 union all
select '10:21:23', 1, 0 union all
select '10:21:24', 1, 0 union all
select '10:21:25', 1, 8 union all
select '10:21:26', 0, 0 union all
select '10:21:27', 0, 4 union all
select '10:21:28', 0, 4 union all
select '10:21:29', 2, 4 union all
select '10:21:30', 2, 4 union all
select '10:21:31', 0, 0 union all
select '10:21:32', 0, 0 union all
select '10:21:33', 0, 0 union all
select '10:21:34', 0, 0 union all
select '10:21:35', 0, 0 union all
select '10:21:36', 1, 0
;with s1
as
(
select TimeStamp,Param1,Param2, row_number() over (order by TimeStamp) as rnk
from @t
)
select ss1.TimeStamp,ss1.Param1,ss1.Param2
from s1 ss1
left join s1 ss2 on ss2.rnk+1=ss1.rnk
where ss1.Param1<>ss2.Param1 or ss1.Param2<>ss2.Param2 or ss2.TimeStamp is null
OE>из нее надо выбрать только те строки, где меняется Param1 или Param2, они отмечены <<. База — MS SQL 2005/2008. Подскажите ключевые слова как это пооптимальнее изобразить.
select top(1) * from tbl
union
select l.* from tbl as l
inner join tbl as r
on l.id = r.id + cast('0:0:01' as datetime)
where l.val1 <> r.val1 or l.val2 <> r.val2
Здравствуйте, Odi$$ey, Вы писали:
OE>из нее надо выбрать только те строки, где меняется Param1 или Param2, они отмечены <<. База — MS SQL 2005/2008. Подскажите ключевые слова как это пооптимальнее изобразить.
Ну я буду очередным хитрецом и отдельное спс Goodkov за предоставленный скрипт генерации исходных данных (что является как-бы минусом топикстартеру).
И еще: на поле TimeStamp надо бы индекс повесить, а то и кластерный.
declare @t TABLE (TimeStamp datetime,Param1 int ,Param2 int)
insert into @t
select '10:21:21', 0, 0 union all
select '10:21:22', 0, 0 union all
select '10:21:23', 1, 0 union all
select '10:21:24', 1, 0 union all
select '10:21:25', 1, 8 union all
select '10:21:26', 0, 0 union all
select '10:21:27', 0, 4 union all
select '10:21:28', 0, 4 union all
select '10:21:29', 2, 4 union all
select '10:21:30', 2, 4 union all
select '10:21:31', 0, 0 union all
select '10:21:32', 0, 0 union all
select '10:21:33', 0, 0 union all
select '10:21:34', 0, 0 union all
select '10:21:35', 0, 0 union all
select '10:21:36', 1, 0
select
t1.*
from
@t t1
outer apply
(select top 1
t2.Param1,
t2.Param2
from
@t t2
where
t2.TimeStamp < t1.TimeStamp
order by
t2.TimeStamp desc
) as Prev
where
t1.Param1 != Prev.Param1 or
t1.Param2 != Prev.Param2 or
Prev.Param1 is null
order by
TimeStamp
;
OE>из нее надо выбрать только те строки, где меняется Param1 или Param2, они отмечены <<. База — MS SQL 2005/2008. Подскажите ключевые слова как это пооптимальнее изобразить.