Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Рекурсивная сортировка / 25 сообщений из 25, страница 1 из 1
15.12.2017, 00:08:49
    #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
15.12.2017, 00:10:10
    #39570031
xandr_ukr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рекурсивная сортировка
Версия сервера 2016
...
Рейтинг: 0 / 0
15.12.2017, 00:26:34
    #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
15.12.2017, 01:51:55
    #39570047
xandr_ukr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рекурсивная сортировка
felix_ff,

По факту Вы оставляете в списке показатели VAL у которых дата позднее максимального значения 92653
...
Рейтинг: 0 / 0
15.12.2017, 02:01:16
    #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
15.12.2017, 02:22:22
    #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
15.12.2017, 07:16:26
    #39570078
Ennor Tiegael
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рекурсивная сортировка
xandr_ukr,

А если водила ошибся в большую сторону один раз, после чего вводил правильно, что будете делать?
...
Рейтинг: 0 / 0
15.12.2017, 07:28:07
    #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
15.12.2017, 07:28:40
    #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
15.12.2017, 08:25:07
    #39570089
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рекурсивная сортировка
xandr_ukrпройтись по списку и выбросить из него те значения VAL которые не являются инкрементальными
Задача неоднозначна.
Пример:
VALDate11/1/132/2/223/3/344/4/4
Какую из записей выбросить - вторую или третью? выбрасывание любой приводит список "в порядок"...
...
Рейтинг: 0 / 0
15.12.2017, 08:26:52
    #39570091
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рекурсивная сортировка
PS. Контролировать надо непосредственно ввод данных, а не итог абы какого ввода.
...
Рейтинг: 0 / 0
15.12.2017, 08:53:58
    #39570097
982183
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рекурсивная сортировка
Совсем недавно что-то подобное обсуждали про сбои в датчиках.
...
Рейтинг: 0 / 0
15.12.2017, 10:29:47
    #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
15.12.2017, 11:41:40
    #39570222
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рекурсивная сортировка
Minamotoесли делать в одном запросе, то нужно сравнивать и с предыдущим значением, и со следующим, и только если с обеими не сходится, тогда запись будет подозрительной.В моём примере опять-таки и 2-я, и 3-я записи "подозрительны". Какую удалять будем?
...
Рейтинг: 0 / 0
15.12.2017, 11:58:18
    #39570235
Minamoto
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рекурсивная сортировка
AkinaMinamotoесли делать в одном запросе, то нужно сравнивать и с предыдущим значением, и со следующим, и только если с обеими не сходится, тогда запись будет подозрительной.В моём примере опять-таки и 2-я, и 3-я записи "подозрительны". Какую удалять будем?
Minamoto(я бы не стал, на самом деле, а отдал бы на ручную перепроверку)
Вопрос то не ко мне, а к ТС и к его требованиям к обработанным данным.
...
Рейтинг: 0 / 0
15.12.2017, 12:30:26
    #39570247
xandr_ukr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рекурсивная сортировка
Валидация данных в момент вставки - не моя компетенция. У меня лишь срез данных, по кторому строю отчет
...
Рейтинг: 0 / 0
15.12.2017, 12:32:09
    #39570250
xandr_ukr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Рекурсивная сортировка
Minamoto,

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

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

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

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

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

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


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