powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Рекурсивная сортировка
25 сообщений из 25, страница 1 из 1
Рекурсивная сортировка
    #39570030
xandr_ukr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день!
Есть список
val date
88943 11/01/17
89111 11/02/17
89288 11/03/17
84598 11/06/17
89683 11/07/17
89777 11/08/17
90012 11/09/17
90191 11/10/17
90622 11/13/17
90666 11/14/17
90987 11/15/17
91111 11/16/17
9099 11/17/17
92056 11/20/17
91417 11/21/17
91954 11/22/17
92653 11/24/17
91934 11/27/17
92125 11/28/17
92307 11/29/17
92484 11/30/17

Он отсортирован по дате
Реально ли пройтись по списку и выбросить из него те значения VAL которые не являются инкрементальными (аля водила ошибался при вводе показаний одометра и надо их убрать из списка). Хотелось бы это сделать без курсоров и темповой таблички
...
Рейтинг: 0 / 0
Рекурсивная сортировка
    #39570031
xandr_ukr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Версия сервера 2016
...
Рейтинг: 0 / 0
Рекурсивная сортировка
    #39570035
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xandr_ukr,

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
declare @t table (val int, date datetime);

insert into @t values 
(88943,	'11/01/17'),
(89111,	'11/02/17'),
(89288,	'11/03/17'),
(84598,	'11/06/17'),
(89683,	'11/07/17'),
(89777,	'11/08/17'),
(90012,	'11/09/17'),
(90191,	'11/10/17'),
(90622,	'11/13/17'),
(90666,	'11/14/17'),
(90987,	'11/15/17'),
(91111,	'11/16/17'),
(9099,	'11/17/17'),
(92056,	'11/20/17'),
(91417,	'11/21/17'),
(91954,	'11/22/17'),
(92653,	'11/24/17'),
(91934,	'11/27/17'),
(92125,	'11/28/17'),
(92307,	'11/29/17'),
(92484,	'11/30/17');

with x as (
select lead(val, 1, null) over (order by date) as lg, val, date from @t
)
delete from x where lg < val;

select * from @t;
...
Рейтинг: 0 / 0
Рекурсивная сортировка
    #39570047
xandr_ukr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
felix_ff,

По факту Вы оставляете в списке показатели VAL у которых дата позднее максимального значения 92653
...
Рейтинг: 0 / 0
Рекурсивная сортировка
    #39570050
xandr_ukr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
По сути вот реализация с курсором (добавлено еще условие что последующий показатель не должен быть на 1500 миль больше валидного предыдущего)
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
DECLARE @tmp table (odom int, dt date, qnt decimal(18,2))

insert into @tmp(odom, dt, qnt)
values
(88943,	'2017-11-01 00:00:00.000',			7.27	),
(89111,	'2017-11-02 00:00:00.000',			6.9	),
(89288,	'2017-11-03 00:00:00.000',			6.99	),
(84598,	'2017-11-06 00:00:00.000',			6.73	),
(89683,	'2017-11-07 00:00:00.000',			8.77	),
(89777,	'2017-11-08 00:00:00.000',			7.83	),
(90012,	'2017-11-09 00:00:00.000',			5.71	),
(90191,	'2017-11-10 00:00:00.000',			7.02	),
(90622,	'2017-11-13 00:00:00.000',			6.79	),
(90666,	'2017-11-14 00:00:00.000',			7.22	),
(90987,	'2017-11-15 00:00:00.000',			7.38	),
(91111,	'2017-11-16 00:00:00.000',			6.97	),
(9099,	'2017-11-17 00:00:00.000',			7.71	),
(92056,	'2017-11-20 00:00:00.000',			6.7	),
(91417,	'2017-11-21 00:00:00.000',			7.22	),
(91954,	'2017-11-22 00:00:00.000',			6.84	),
(92653,	'2017-11-24 00:00:00.000',			6.03	),
(91934,	'2017-11-27 00:00:00.000',			7.42	),
(92125,	'2017-11-28 00:00:00.000',			7.52	),
(92307,	'2017-11-29 00:00:00.000',			7.26	),
(92484,	'2017-11-30 00:00:00.000',			6.87	)

DECLARE @tmp_clear table (odom int, dt date, qnt decimal(18,2))
declare v_cur CURSOR FOR select odom, dt, qnt from @tmp order by dt;
declare @v_odom int, @v_dt date, @v_cur_odom int, @v_qnt decimal(18,2);

open v_cur
FETCH NEXT FROM v_cur INTO @v_odom, @v_dt, @v_qnt
WHILE @@FETCH_STATUS = 0
BEGIN
	select @v_cur_odom = max(odom) from @tmp_clear

	IF (@v_odom > @v_cur_odom AND @v_odom - @v_cur_odom < 1500)
	OR @v_cur_odom IS NULL 
	
		INSERT INTO @tmp_clear values(@v_odom, @v_dt, @v_qnt)
		FETCH NEXT FROM v_cur INTO @v_odom, @v_dt, @v_qnt
END

CLOSE v_cur
DEALLOCATE  v_cur

select  * from @tmp_clear
...
Рейтинг: 0 / 0
Рекурсивная сортировка
    #39570056
xandr_ukr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот еще проще, но с курсором (а хотелось бы без него)
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
DECLARE @tmp table (odom int, dt date, qnt decimal(18,2))

insert into @tmp(odom, dt, qnt)
values
(88943,	'2017-11-01 00:00:00.000',			7.27	),
(89111,	'2017-11-02 00:00:00.000',			6.9		),
(89288,	'2017-11-03 00:00:00.000',			6.99	),
(84598,	'2017-11-06 00:00:00.000',			6.73	),
(89683,	'2017-11-07 00:00:00.000',			8.77	),
(89777,	'2017-11-08 00:00:00.000',			7.83	),
(90012,	'2017-11-09 00:00:00.000',			5.71	),
(90191,	'2017-11-10 00:00:00.000',			7.02	),
(90622,	'2017-11-13 00:00:00.000',			6.79	),
(90666,	'2017-11-14 00:00:00.000',			7.22	),
(90987,	'2017-11-15 00:00:00.000',			7.38	),
(91111,	'2017-11-16 00:00:00.000',			6.97	),
(9099,	'2017-11-17 00:00:00.000',			7.71	),
(92056,	'2017-11-20 00:00:00.000',			6.7	),
(91417,	'2017-11-21 00:00:00.000',			7.22	),
(91954,	'2017-11-22 00:00:00.000',			6.84	),
(92653,	'2017-11-24 00:00:00.000',			6.03	),
(91934,	'2017-11-27 00:00:00.000',			7.42	),
(92125,	'2017-11-28 00:00:00.000',			7.52	),
(92307,	'2017-11-29 00:00:00.000',			7.26	),
(92484,	'2017-11-30 00:00:00.000',			6.87	)

DECLARE @tmp_clear table (odom int, dt date, qnt decimal(18,2))
declare v_cur CURSOR FOR select odom, dt, qnt from @tmp order by dt;
declare @v_odom int, @v_dt date, @v_cur_odom int, @v_qnt decimal(18,2);

open v_cur
FETCH NEXT FROM v_cur INTO @v_odom, @v_dt, @v_qnt

WHILE @@FETCH_STATUS = 0
BEGIN

	IF (@v_odom > @v_cur_odom AND @v_odom - @v_cur_odom < 1500)
	OR @v_cur_odom IS NULL
	BEGIN
		INSERT INTO @tmp_clear values(@v_odom, @v_dt, @v_qnt)
		SET @v_cur_odom = @v_odom
	END
	FETCH NEXT FROM v_cur INTO @v_odom, @v_dt, @v_qnt
END

CLOSE v_cur
DEALLOCATE  v_cur

select  * from @tmp_clear
...
Рейтинг: 0 / 0
Рекурсивная сортировка
    #39570078
Фотография Ennor Tiegael
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xandr_ukr,

А если водила ошибся в большую сторону один раз, после чего вводил правильно, что будете делать?
...
Рейтинг: 0 / 0
Рекурсивная сортировка
    #39570079
Фотография Ennor Tiegael
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если же буквально, то вот:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
declare @t table (Amount int, DT date);

insert into @t values 
(88943,	'11/01/17'),
(89111,	'11/02/17'),
(89288,	'11/03/17'),
(84598,	'11/06/17'),
(89683,	'11/07/17'),
(89777,	'11/08/17'),
(90012,	'11/09/17'),
(90191,	'11/10/17'),
(90622,	'11/13/17'),
(90666,	'11/14/17'),
(90987,	'11/15/17'),
(91111,	'11/16/17'),
(9099,	'11/17/17'),
(92056,	'11/20/17'),
(91417,	'11/21/17'),
(91954,	'11/22/17'),
(92653,	'11/24/17'),
(91934,	'11/27/17'),
(92125,	'11/28/17'),
(92307,	'11/29/17'),
(92484,	'11/30/17');

with cte as (
	select t.*, max(t.Amount) over(order by t.DT) as [MaxAmount] from @t t
)
select c.DT, c.Amount
from cte c
where c.Amount = c.MaxAmount
order by c.DT;


По сути, вариант felix_ff, только учитывается не одно значение, а все.
...
Рейтинг: 0 / 0
Рекурсивная сортировка
    #39570080
aleks222
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DECLARE @tmp table (odom int, dt date, qnt decimal(18,2))

insert into @tmp(odom, dt, qnt)
values
(88943, '2017-11-01 00:00:00.000', 7.27 ),
(89111, '2017-11-02 00:00:00.000', 6.9 ),
(89288, '2017-11-03 00:00:00.000', 6.99 ),
(84598, '2017-11-06 00:00:00.000', 6.73 ),
(89683, '2017-11-07 00:00:00.000', 8.77 ),
(89777, '2017-11-08 00:00:00.000', 7.83 ),
(90012, '2017-11-09 00:00:00.000', 5.71 ),
(90191, '2017-11-10 00:00:00.000', 7.02 ),
(90622, '2017-11-13 00:00:00.000', 6.79 ),
(90666, '2017-11-14 00:00:00.000', 7.22 ),
(90987, '2017-11-15 00:00:00.000', 7.38 ),
(91111, '2017-11-16 00:00:00.000', 6.97 ),
(9099, '2017-11-17 00:00:00.000', 7.71 ),
(92056, '2017-11-20 00:00:00.000', 6.7 ),
(91417, '2017-11-21 00:00:00.000', 7.22 ),
(91954, '2017-11-22 00:00:00.000', 6.84 ),
(92653, '2017-11-24 00:00:00.000', 6.03 ),
(91934, '2017-11-27 00:00:00.000', 7.42 ),
(92125, '2017-11-28 00:00:00.000', 7.52 ),
(92307, '2017-11-29 00:00:00.000', 7.26 ),
(92484, '2017-11-30 00:00:00.000', 6.87 );


DECLARE @clear table (odom int, dt date, qnt decimal(18,2), primary key(odom, dt));

insert @clear select * from @tmp;

declare @rc int = @@rowcount;

while @rc > 0 begin

with t as ( select * from @clear )
delete t
from t cross apply( select top(1) * from t as tt where tt.dt < t.dt order by tt.dt desc ) as p
where t.odom < p.odom;
set @rc = @@rowcount;

with t as ( select * from @clear )
delete t
from t cross apply( select top(1) * from t as tt where tt.dt < t.dt order by tt.dt desc ) as p
where t.odom - p.odom >= 1500;
set @rc = @rc + @@rowcount;

end;

select * from @clear order by dt;
...
Рейтинг: 0 / 0
Рекурсивная сортировка
    #39570089
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xandr_ukrпройтись по списку и выбросить из него те значения VAL которые не являются инкрементальными
Задача неоднозначна.
Пример:
VALDate11/1/132/2/223/3/344/4/4
Какую из записей выбросить - вторую или третью? выбрасывание любой приводит список "в порядок"...
...
Рейтинг: 0 / 0
Рекурсивная сортировка
    #39570091
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PS. Контролировать надо непосредственно ввод данных, а не итог абы какого ввода.
...
Рейтинг: 0 / 0
Рекурсивная сортировка
    #39570097
982183
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Совсем недавно что-то подобное обсуждали про сбои в датчиках.
...
Рейтинг: 0 / 0
Рекурсивная сортировка
    #39570154
Minamoto
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xandr_ukr, если делать в одном запросе, то нужно сравнивать и с предыдущим значением, и со следующим, и только если с обеими не сходится, тогда запись будет подозрительной.

Примерно вот так, я просто пометил подозрительные строки, если захотите их удалить (я бы не стал, на самом деле, а отдал бы на ручную перепроверку), то просто перенесите условие в where для запроса на удаление:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
declare @t table (Amount int, DT date);

insert into @t values 
(88943,	'11/01/17'),
(89111,	'11/02/17'),
(89288,	'11/03/17'),
(84598,	'11/06/17'),
(89683,	'11/07/17'),
(89777,	'11/08/17'),
(90012,	'11/09/17'),
(90191,	'11/10/17'),
(90622,	'11/13/17'),
(90666,	'11/14/17'),
(90987,	'11/15/17'),
(91111,	'11/16/17'),
(9099,	'11/17/17'),
(92056,	'11/20/17'),
(91417,	'11/21/17'),
(91954,	'11/22/17'),
(92653,	'11/24/17'),
(91934,	'11/27/17'),
(92125,	'11/28/17'),
(92307,	'11/29/17'),
(92484,	'11/30/17');

select  *
    ,   lead(t.Amount, 1) over (order by DT) - t.Amount
    ,   t.Amount - lag(t.Amount, 1) over (order by DT)
    ,  case 
        when not(lead(t.Amount, 1) over (order by DT) - t.Amount between 0 and 1500) and
             not(t.Amount - lag(t.Amount, 1) over (order by DT) between 0 and 1500) 
          then 1 end 
from    @t as t 
...
Рейтинг: 0 / 0
Рекурсивная сортировка
    #39570222
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Minamotoесли делать в одном запросе, то нужно сравнивать и с предыдущим значением, и со следующим, и только если с обеими не сходится, тогда запись будет подозрительной.В моём примере опять-таки и 2-я, и 3-я записи "подозрительны". Какую удалять будем?
...
Рейтинг: 0 / 0
Рекурсивная сортировка
    #39570235
Minamoto
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AkinaMinamotoесли делать в одном запросе, то нужно сравнивать и с предыдущим значением, и со следующим, и только если с обеими не сходится, тогда запись будет подозрительной.В моём примере опять-таки и 2-я, и 3-я записи "подозрительны". Какую удалять будем?
Minamoto(я бы не стал, на самом деле, а отдал бы на ручную перепроверку)
Вопрос то не ко мне, а к ТС и к его требованиям к обработанным данным.
...
Рейтинг: 0 / 0
Рекурсивная сортировка
    #39570247
xandr_ukr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Валидация данных в момент вставки - не моя компетенция. У меня лишь срез данных, по кторому строю отчет
...
Рейтинг: 0 / 0
Рекурсивная сортировка
    #39570250
xandr_ukr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Minamoto,

Ваш запрос исключает из списка значение 92056, а оно должно быть включено т.к. соседнее после 91111
...
Рейтинг: 0 / 0
Рекурсивная сортировка
    #39570252
xandr_ukr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akina,

В Вашем случае верно будет вернуть список 1,3,4
...
Рейтинг: 0 / 0
Рекурсивная сортировка
    #39570258
xandr_ukrAkina,

В Вашем случае верно будет вернуть список 1,3,4а каков формальный критерий этой верности?
...
Рейтинг: 0 / 0
Рекурсивная сортировка
    #39570260
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xandr_ukrВ Вашем случае верно будет вернуть список 1,3,4Обоснуйте. Как по мне, так список 1,2,4 ничем не хуже...
...
Рейтинг: 0 / 0
Рекурсивная сортировка
    #39570261
Minamoto
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xandr_ukrMinamoto,

Ваш запрос исключает из списка значение 92056, а оно должно быть включено т.к. соседнее после 91111
А после него идут 91417, 91954, значит они - невалидные?
...
Рейтинг: 0 / 0
Рекурсивная сортировка
    #39570273
xandr_ukr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Minamoto,

Да, они невалидные т.к. уже меньше предыдущего максимального на тот момент - 92056
...
Рейтинг: 0 / 0
Рекурсивная сортировка
    #39570275
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
xandr_ukr , а если "водила ошибся при вводе показаний одометра" и залепил в показания офигеть большое число (скажем, цифра задвоилась, а он прозевал) - то ты так всю историю после этой ошибки удалишь?
...
Рейтинг: 0 / 0
Рекурсивная сортировка
    #39570317
Руслан Дамирович
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что, неужели найти точки экстремумов и выкинуть их на помойку?
...
Рейтинг: 0 / 0
Рекурсивная сортировка
    #39570899
iii2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Руслан ДамировичЧто, неужели найти точки экстремумов и выкинуть их на помойку?
Да нет, эта задача, похоже, на локальную фильтрацию, ну или полосовую фильтрацию.
Ну там, "левый фильтр" - значение должно быть больше предыдущего, "правый фильтр" - меньше следующего, "срединный фильтр" - в диапазоне между n + 2 и n - 2 значением.
Сглаживание, короче.

ТС пусть вспомнит соответствующий курс из матстатистики, и скажет, какой из вариантов сглаживания его больше устраивает.
...
Рейтинг: 0 / 0
25 сообщений из 25, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Рекурсивная сортировка
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]