Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Предыдущее значение вычисляемого поля / 25 сообщений из 46, страница 1 из 2
09.04.2018, 15:47
    #39627580
ferzmikk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предыдущее значение вычисляемого поля
Здравствуйте!

Есть SQL-запрос.
SQL-запрос
Код: 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.
50.
51.
52.
Declare @ДельтаПредел decimal(5,2) = 0.07;
DECLARE @Таблица table(	
	[Клиент] varchar(8),
	[Код юр лица] varchar(12),
	[Код ТТ] varchar(8),	
	[Код продукции] varchar(8),
	[Дата] date,
	[Цена] numeric(8,0)
	)	
;

INSERT INTO
  @Таблица
VALUES 
('Клиент', 'Код юр лица1', 'Код ТТ1','SKU1', '01.01.2014', 100),
('Клиент', 'Код юр лица1', 'Код ТТ1','SKU1', '02.01.2014', 100),
('Клиент', 'Код юр лица1', 'Код ТТ1','SKU1', '03.01.2014', 80),
('Клиент', 'Код юр лица1', 'Код ТТ1','SKU1', '04.01.2014', 80),
('Клиент', 'Код юр лица1', 'Код ТТ1','SKU1', '05.01.2014', 100);

SELECT
	Т2.[Клиент],
	Т2.[Код юр лица],
	Т2.[Код ТТ],	
	Т2.[Код продукции],
	Т2.[Дата],
	Т2.[Цена],
	Т2.[Цена пред],		
	(CASE
		WHEN ([Цена пред] IS NOT NULL) AND (([Цена]/[Цена пред])-1) <= -@ДельтаПредел THEN
			1
		ELSE
			0
		END) AS [Маркировка скидки]
FROM
	(SELECT
		[Клиент],
		[Код юр лица],
		[Код ТТ],	
		[Код продукции],
		[Дата],
		[Цена],
		LAG([Цена]) OVER(Partition by [Клиент], [Код юр лица], [Код ТТ],[Код продукции] ORDER BY  [Дата]) AS [Цена пред]		
	FROM
		@Таблица
	/*ORDER BY
		[Клиент],
		[Код юр лица],
		[Код ТТ],	
		[Код продукции],
		[Дата]*/
	) AS Т2

Выдает такой результат
Клиент Код юр лица Код ТТ Код продукции Дата Цена Цена пред Маркировка скидкиКлиент Код юр лица1 Код ТТ1 SKU1 2014-01-01 100 NULL 0Клиент Код юр лица1 Код ТТ1 SKU1 2014-01-02 100 100 0Клиент Код юр лица1 Код ТТ1 SKU1 2014-01-03 80 100 1 Клиент Код юр лица1 Код ТТ1 SKU1 2014-01-04 80 80 0 Клиент Код юр лица1 Код ТТ1 SKU1 2014-01-05 100 80 0
Не обращайте внимание что название полей на русском языке, это для примера и для понятности. А также не придаем значение базовой цены. Просто сравниваем с предыдущей строкой.

На четвертой строке вместо 0 должен быть 1. А для этого нужно вытащить предыдущее значение вычисляемого поля Маркировка .

То есть написать типа так
SQL-Запрос
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
	(CASE
		WHEN ([Цена пред] IS NOT NULL) AND (([Цена]/[Цена пред])-1) <= -@ДельтаПредел THEN
			1
		ELSE
			(CASE
				WHEN  (([Цена]/[Цена пред])-1) <= @ДельтаПредел AND [Маркировка скидки пред] =1 THEN
					1
				ELSE
					0
				END)
			END)
		END) AS [Маркировка скидки]


1. Как вытягивать предыдущее значение вычисляемого поля?

2. Order By не работает во вложенном запросе. В рабочем коде используются табличные выражения и вложенные запросы. Как можно обойти эту проблему?
...
Рейтинг: 0 / 0
09.04.2018, 16:12
    #39627595
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предыдущее значение вычисляемого поля
ferzmikkКак вытягивать предыдущее значение вычисляемого поля?LEAD()

ferzmikkOrder By не работает во вложенном запросе.ORDER BY в промежуточных итогах используется только в том случае, когда влияет на список записей выходного набора. Без ограничения количества возвращаемых записей простая сортировка на набор не влияет - а потому игнорируется.
...
Рейтинг: 0 / 0
09.04.2018, 16:48
    #39627616
ferzmikk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предыдущее значение вычисляемого поля
AkinaferzmikkКак вытягивать предыдущее значение вычисляемого поля?LEAD()
LEAD вытягивает из последующей строки, а надо из предыдущей. А также по текущей строке при расчете вычисляемого поля [Маркировка скидки] нужно вытянуть рассчитанное значение этого же поля предыдущей строки.
...
Рейтинг: 0 / 0
09.04.2018, 16:52
    #39627618
ferzmikk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предыдущее значение вычисляемого поля
AkinaferzmikkOrder By не работает во вложенном запросе.ORDER BY в промежуточных итогах используется только в том случае, когда влияет на список записей выходного набора. Без ограничения количества возвращаемых записей простая сортировка на набор не влияет - а потому игнорируется.
Поскольку во вложенном запросе я использую оконную функция Lag, то актуально делать сортировку, если я не ошибаюсь.
...
Рейтинг: 0 / 0
09.04.2018, 16:57
    #39627621
Akina
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предыдущее значение вычисляемого поля
ferzmikkПоскольку во вложенном запросе я использую оконную функция Lag, то актуально делать сортировку, если я не ошибаюсь.LAG() имеет свой собственный класс ORDER BY и не зависит от внешнего.
...
Рейтинг: 0 / 0
09.04.2018, 17:24
    #39627629
ferzmikk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предыдущее значение вычисляемого поля
ferzmikkAkinaпропущено...
LEAD()
LEAD вытягивает из последующей строки, а надо из предыдущей. А также по текущей строке при расчете вычисляемого поля [Маркировка скидки] нужно вытянуть рассчитанное значение этого же поля предыдущей строки.
А тут как?
...
Рейтинг: 0 / 0
09.04.2018, 17:53
    #39627635
Дедушка
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предыдущее значение вычисляемого поля
ferzmikkА тут как?делать в два прохода
...
Рейтинг: 0 / 0
09.04.2018, 19:50
    #39627657
ferzmikk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предыдущее значение вычисляемого поля
Тут расчет получается последовательным как в excel.

На скриншоте для ячейки P14 нужно выйти на P13, для P15 нужно выйти на P14.

Никак получается.

Как написать запрос?
...
Рейтинг: 0 / 0
09.04.2018, 20:11
    #39627659
court
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предыдущее значение вычисляемого поля
ferzmikkКак написать запрос?"рекурсивно",
в смысле рекурсивный запрос :)
...
Рейтинг: 0 / 0
09.04.2018, 20:30
    #39627661
court
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предыдущее значение вычисляемого поля
courtferzmikkКак написать запрос?"рекурсивно",
в смысле рекурсивный запрос :)
Код: 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.
Declare @ДельтаПредел decimal(5,2) = 0.07;
DECLARE @Таблица table(	
	[Клиент] varchar(8),
	[Код юр лица] varchar(12),
	[Код ТТ] varchar(8),	
	[Код продукции] varchar(8),
	[Дата] date,
	[Цена] numeric(8,0)
	)	
;

INSERT INTO
  @Таблица
VALUES 
('Клиент', 'Код юр лица1', 'Код ТТ1','SKU1', '01.01.2014', 100),
('Клиент', 'Код юр лица1', 'Код ТТ1','SKU1', '02.01.2014', 100),
('Клиент', 'Код юр лица1', 'Код ТТ1','SKU1', '03.01.2014', 80),
('Клиент', 'Код юр лица1', 'Код ТТ1','SKU1', '04.01.2014', 80),
('Клиент', 'Код юр лица1', 'Код ТТ1','SKU1', '05.01.2014', 100);

;with T as (
	select *, id=ROW_NUMBER()over(order by [Дата]) from @Таблица),
cte as (
	select *, cast(null as numeric(8,0)) as [Цена пред], 0 as [Маркировка скидки] from T
	where id=1
	
	union all
	
	select t.*, cte.[Цена], 
		CASE
			WHEN ([Цена пред] IS NOT NULL) AND ((t.Цена/[Цена пред])-1) <= -@ДельтаПредел THEN
				1
			ELSE
				CASE
					WHEN  ((t.[Цена]/[Цена пред])-1) <= @ДельтаПредел AND cte.[Маркировка скидки] =1 THEN
						1
					ELSE
						0
				END
		END
	
		
		from cte inner join t on t.id=cte.id+1)
		
select * from cte order by id			



КлиентКод юр лицаКод ТТКод продукцииДатаЦенаidЦена предМаркировка скидкиКлиентКод юр лица1Код ТТ1SKU12014-01-011001NULL0КлиентКод юр лица1Код ТТ1SKU12014-01-0210021000КлиентКод юр лица1Код ТТ1SKU12014-01-038031001КлиентКод юр лица1Код ТТ1SKU12014-01-04804801КлиентКод юр лица1Код ТТ1SKU12014-01-051005800
...
Рейтинг: 0 / 0
09.04.2018, 20:37
    #39627664
ferzmikk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предыдущее значение вычисляемого поля
court,

Спасибо, буду разбирать!
...
Рейтинг: 0 / 0
09.04.2018, 22:08
    #39627685
invm
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предыдущее значение вычисляемого поля
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
with t as
(
 select
  *,
  LAG([Цена], 1) OVER(Partition by [Клиент], [Код юр лица], [Код ТТ],[Код продукции] ORDER BY  [Дата]) as p1,
  LAG([Цена], 2) OVER(Partition by [Клиент], [Код юр лица], [Код ТТ],[Код продукции] ORDER BY  [Дата]) as p2
 from
  @Таблица
)
select
 Клиент,
 [Код юр лица],
 [Код ТТ],
 [Код продукции],
 Дата,
 Цена,
 p1 as [Цена пред],
 case
  when p1/p2 - 1 <= -@ДельтаПредел or [Цена]/p1 - 1 <= -@ДельтаПредел then 1
  else 0
 end
from
 t;

?
...
Рейтинг: 0 / 0
10.04.2018, 07:50
    #39627732
ferzmikk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предыдущее значение вычисляемого поля
invm,

Если добавить еще строки в исходных данных

Код: 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.
Declare @ДельтаПредел decimal(5,2) = 0.07;
DECLARE @Таблица table(	
	[Клиент] varchar(8),
	[Код юр лица] varchar(12),
	[Код ТТ] varchar(8),	
	[Код продукции] varchar(8),
	[Дата] date,
	[Цена] numeric(8,0)
	)	
;

INSERT INTO
  @Таблица
VALUES 
('Клиент', 'Код юр лица1', 'Код ТТ1','SKU1', '01.01.2014', 100),
('Клиент', 'Код юр лица1', 'Код ТТ1','SKU1', '02.01.2014', 100),
('Клиент', 'Код юр лица1', 'Код ТТ1','SKU1', '03.01.2014', 80),
('Клиент', 'Код юр лица1', 'Код ТТ1','SKU1', '04.01.2014', 80),
('Клиент', 'Код юр лица1', 'Код ТТ1','SKU1', '05.01.2014', 80),
('Клиент', 'Код юр лица1', 'Код ТТ1','SKU1', '06.01.2014', 80),
('Клиент', 'Код юр лица1', 'Код ТТ1','SKU1', '07.01.2014', 100);

with t as
(
 select
  *,
  LAG([Цена], 1) OVER(Partition by [Клиент], [Код юр лица], [Код ТТ],[Код продукции] ORDER BY  [Дата]) as p1,
  LAG([Цена], 2) OVER(Partition by [Клиент], [Код юр лица], [Код ТТ],[Код продукции] ORDER BY  [Дата]) as p2
 from
  @Таблица
)
select
 Клиент,
 [Код юр лица],
 [Код ТТ],
 [Код продукции],
 Дата,
 Цена,
 p1 as [Цена пред],
 case
  when p1/p2 - 1 <= -@ДельтаПредел or [Цена]/p1 - 1 <= -@ДельтаПредел then 1
  else 0
 end
from
 t;

то результат будет таким
Клиент Код юр лица Код ТТ Код продукции Дата Цена Цена пред (Отсутствует имя столбца)Клиент Код юр лица1 Код ТТ1 SKU1 2014-01-01 100 NULL 0Клиент Код юр лица1 Код ТТ1 SKU1 2014-01-02 100 100 0Клиент Код юр лица1 Код ТТ1 SKU1 2014-01-03 80 100 1Клиент Код юр лица1 Код ТТ1 SKU1 2014-01-04 80 80 1Клиент Код юр лица1 Код ТТ1 SKU1 2014-01-05 80 80 0 Клиент Код юр лица1 Код ТТ1 SKU1 2014-01-06 80 80 0 Клиент Код юр лица1 Код ТТ1 SKU1 2014-01-07 100 80 0
...
Рейтинг: 0 / 0
10.04.2018, 08:09
    #39627734
ferzmikk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предыдущее значение вычисляемого поля
court,

При таком запросе
Код: 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.
50.
51.
52.
53.
54.
Declare @ДельтаПредел decimal(5,2) = 0.07;
DECLARE @Таблица table(	
	[Клиент] varchar(8),
	[Код юр лица] varchar(12),
	[Код ТТ] varchar(8),	
	[Код продукции] varchar(8),
	[Дата] date,
	[Цена] numeric(8,0)
	)	
;

INSERT INTO
  @Таблица
VALUES 
('Клиент', 'Код юр лица1', 'Код ТТ1','SKU1', '01.01.2014', 100),
('Клиент', 'Код юр лица1', 'Код ТТ1','SKU1', '02.01.2014', 100),
('Клиент', 'Код юр лица1', 'Код ТТ1','SKU1', '03.01.2014', 80),
('Клиент', 'Код юр лица1', 'Код ТТ1','SKU1', '06.01.2014', 100);
;

WITH T as (
	SELECT
		*,
		id=ROW_NUMBER()over(order by [Клиент], [Код юр лица], [Код ТТ], [Код продукции], [Дата]) from @Таблица),
		cte as (
			select
				*,
				cast(null as numeric(8,0)) as [Цена пред],
				0 as [Маркировка скидки]
			from
				T
			where
				id=1	
	union all
	
	select
		t.*,
		cte.[Цена], 
		CASE
			WHEN ([Цена пред] IS NOT NULL) AND ((t.Цена/[Цена пред])-1) <= -@ДельтаПредел THEN
				1
			ELSE
				CASE
					WHEN  ((t.[Цена]/[Цена пред])-1) <= @ДельтаПредел AND cte.[Маркировка скидки] =1 THEN
						1
					ELSE
						0
				END
		END
	
		
		from cte inner join t on t.id=cte.id+1)
		
select * from cte order by id	

выдает такой результат
Клиент Код юр лица Код ТТ Код продукции Дата Цена id Цена пред Маркировка скидкиКлиент Код юр лица1 Код ТТ1 SKU1 2014-01-01 100 1 NULL 0Клиент Код юр лица1 Код ТТ1 SKU1 2014-01-02 100 2 100 0Клиент Код юр лица1 Код ТТ1 SKU1 2014-01-03 80 3 100 1 Клиент Код юр лица1 Код ТТ1 SKU1 2014-01-06 100 4 80 1
...
Рейтинг: 0 / 0
10.04.2018, 08:11
    #39627736
ferzmikk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предыдущее значение вычисляемого поля
court,

И еще, при использовании рекурсии, когда много строк, то запрос намного дольше выполянется. Возможно ли как то ускорить?
...
Рейтинг: 0 / 0
10.04.2018, 08:44
    #39627743
ferzmikk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предыдущее значение вычисляемого поля
ferzmikkcourt,

И еще, при использовании рекурсии, когда много строк, то запрос намного дольше выполянется. Возможно ли как то ускорить?
165 строк - 2 мин 36 сек
...
Рейтинг: 0 / 0
10.04.2018, 09:57
    #39627780
court
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предыдущее значение вычисляемого поля
ferzmikkcourt,

При таком запросе
Код: 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.
50.
51.
52.
53.
54.
Declare @ДельтаПредел decimal(5,2) = 0.07;
DECLARE @Таблица table(	
	[Клиент] varchar(8),
	[Код юр лица] varchar(12),
	[Код ТТ] varchar(8),	
	[Код продукции] varchar(8),
	[Дата] date,
	[Цена] numeric(8,0)
	)	
;

INSERT INTO
  @Таблица
VALUES 
('Клиент', 'Код юр лица1', 'Код ТТ1','SKU1', '01.01.2014', 100),
('Клиент', 'Код юр лица1', 'Код ТТ1','SKU1', '02.01.2014', 100),
('Клиент', 'Код юр лица1', 'Код ТТ1','SKU1', '03.01.2014', 80),
('Клиент', 'Код юр лица1', 'Код ТТ1','SKU1', '06.01.2014', 100);
;

WITH T as (
	SELECT
		*,
		id=ROW_NUMBER()over(order by [Клиент], [Код юр лица], [Код ТТ], [Код продукции], [Дата]) from @Таблица),
		cte as (
			select
				*,
				cast(null as numeric(8,0)) as [Цена пред],
				0 as [Маркировка скидки]
			from
				T
			where
				id=1	
	union all
	
	select
		t.*,
		cte.[Цена], 
		CASE
			WHEN ([Цена пред] IS NOT NULL) AND ((t.Цена/[Цена пред])-1) <= -@ДельтаПредел THEN
				1
			ELSE
				CASE
					WHEN  ((t.[Цена]/[Цена пред])-1) <= @ДельтаПредел AND cte.[Маркировка скидки] =1 THEN
						1
					ELSE
						0
				END
		END
	
		
		from cte inner join t on t.id=cte.id+1)
		
select * from cte order by id	


выдает такой результат
Клиент Код юр лица Код ТТ Код продукции Дата Цена id Цена пред Маркировка скидкиКлиент Код юр лица1 Код ТТ1 SKU1 2014-01-01 100 1 NULL 0Клиент Код юр лица1 Код ТТ1 SKU1 2014-01-02 100 2 100 0Клиент Код юр лица1 Код ТТ1 SKU1 2014-01-03 80 3 100 1 Клиент Код юр лица1 Код ТТ1 SKU1 2014-01-06 100 4 80 1 это исправь (желтым выделено)
Код: 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.
WITH T as (
	SELECT
		*,
		id=ROW_NUMBER()over(order by [Клиент], [Код юр лица], [Код ТТ], [Код продукции], [Дата]) from @Таблица),
		cte as (
			select
				*,
				t.[Цена] as [Цена пред],	--cast(null as numeric(8,0)) as [Цена пред],
				0 as [Маркировка скидки]
				,[Цена пред которая используется в расчете]=cast(null as numeric(8,0))
			from
				T
			where
				id=1	
	union all
	
	select
		t.*,
		t.[Цена], -- cte.[Цена], 
		CASE
			WHEN ([Цена пред] IS NOT NULL) AND ((1.0*t.Цена/[Цена пред])-1) <= -@ДельтаПредел THEN
				1
			ELSE
				CASE
					WHEN  ((t.[Цена]/[Цена пред])-1) <= @ДельтаПредел AND cte.[Маркировка скидки] =1 THEN
						1
					ELSE
						0
				END
		END
		,cte.[Цена пред]
		
	from cte inner join t on t.id=cte.id+1)
		
select * from cte order by id



[Цена пред которая используется в расчете] - это для понимания, что там вообще происходит, если нужно
...
Рейтинг: 0 / 0
10.04.2018, 12:19
    #39627864
ferzmikk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предыдущее значение вычисляемого поля
court,

В условном примере правильно работает, а в рабочем - не правильно. Не могу понять.
...
Рейтинг: 0 / 0
10.04.2018, 12:30
    #39627873
ferzmikk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предыдущее значение вычисляемого поля
...
Рейтинг: 0 / 0
10.04.2018, 12:32
    #39627874
ferzmikk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предыдущее значение вычисляемого поля
ferzmikkcourt,

В условном примере правильно работает, а в рабочем - не правильно. Не могу понять.
Разобрался. В другой части кода надо было не так писать
Код: sql
1.
LAG([Цена]) OVER(Partition by [Клиент],[Код юрлица],[Код ТТ],[Код продукции] ORDER BY [Дата] ) [Цена пред]


а так
Код: sql
1.
LAG([Цена]) OVER(Partition by [Клиент],[Код юрлица],[Код ТТ],[Код продукции] ORDER BY Convert(datetime,[Дата],104) ) [Цена пред]


и из за этого неправильно сортировался, следовательно, неправильно маркировались.
...
Рейтинг: 0 / 0
10.04.2018, 14:31
    #39627948
ferzmikk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предыдущее значение вычисляемого поля
Из за рекурсии подтормаживает сильно. Возможно ли как то ускорить выгрузку?
...
Рейтинг: 0 / 0
10.04.2018, 16:24
    #39628022
ferzmikk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предыдущее значение вычисляемого поля
ferzmikkИз за рекурсии подтормаживает сильно. Возможно ли как то ускорить выгрузку?
65000 строк. Обрабатывает более 2 часов.

Может быть в ON еще связку указать?
...
Рейтинг: 0 / 0
12.04.2018, 11:42
    #39628957
ferzmikk
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предыдущее значение вычисляемого поля
Обнаружил не учтенный момент.
SQL-запрос
Код: 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.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
Declare @ДельтаПредел decimal(5,2) = 0.07;
DECLARE @Таблица table(	
	[Клиент] varchar(8),
	[Код юр лица] varchar(12),
	[Код ТТ] varchar(8),	
	[Код продукции] varchar(8),
	[Дата] date,
	[Цена] numeric(8,0)
	)	
;

INSERT INTO
  @Таблица
VALUES 
('Клиент1', 'Код юр лица1', 'Код ТТ1','SKU1', '01.01.2014', 100),
('Клиент1', 'Код юр лица1', 'Код ТТ1','SKU1', '02.01.2014', 80),
('Клиент1', 'Код юр лица1', 'Код ТТ1','SKU1', '03.01.2014', 80),
('Клиент1', 'Код юр лица1', 'Код ТТ1','SKU1', '04.01.2014', 80),
('Клиент1', 'Код юр лица1', 'Код ТТ1','SKU1', '05.01.2014', 100),
('Клиент1', 'Код юр лица1', 'Код ТТ1','SKU1', '06.01.2014', 100),
('Клиент1', 'Код юр лица1', 'Код ТТ1','SKU2', '01.01.2014', 50),
('Клиент1', 'Код юр лица1', 'Код ТТ1','SKU2', '02.01.2014', 100),
('Клиент1', 'Код юр лица1', 'Код ТТ1','SKU2', '03.01.2014', 80),
('Клиент1', 'Код юр лица1', 'Код ТТ1','SKU2', '04.01.2014', 80),
('Клиент1', 'Код юр лица1', 'Код ТТ1','SKU2', '05.01.2014', 100),
('Клиент1', 'Код юр лица1', 'Код ТТ1','SKU2', '06.01.2014', 100),
('Клиент1', 'Код юр лица1', 'Код ТТ2','SKU1', '01.01.2014', 60),
('Клиент1', 'Код юр лица1', 'Код ТТ2','SKU1', '02.01.2014', 100),
('Клиент1', 'Код юр лица1', 'Код ТТ2','SKU1', '03.01.2014', 80),
('Клиент1', 'Код юр лица1', 'Код ТТ2','SKU1', '04.01.2014', 80),
('Клиент1', 'Код юр лица1', 'Код ТТ2','SKU1', '05.01.2014', 100),
('Клиент1', 'Код юр лица1', 'Код ТТ2','SKU1', '06.01.2014', 100);

WITH T AS (
	SELECT
		*,
		id=ROW_NUMBER()over(order by [Клиент], [Код юр лица], [Код ТТ], [Код продукции], [Дата]) from @Таблица),
		cte as (
			select
				*,
				t.Цена as [Цена пред],
				0 as [Маркировка скидки],
				[Цена пред которая используется в расчете]=cast(null as numeric(8,0))
			from
				T
			where
				id=1	
	UNION ALL	
	SELECT
		t.*,
		t.[Цена], 
		CASE
			WHEN (cte.[Цена пред] IS NOT NULL) AND ((t.[Цена]/cte.[Цена пред])-1) <= -@ДельтаПредел THEN
				1
			ELSE
				CASE
					WHEN  ((t.[Цена]/cte.[Цена пред])-1) <= @ДельтаПредел AND cte.[Маркировка скидки] =1 THEN
						1
					ELSE
						0
				END
		END,
		cte.[Цена пред]	
	FROM
		cte
	INNER JOIN
		t
	ON
		t.id=cte.id+1)
		
SELECT
	*
FROM
	cte
ORDER BY
	id	

выдает такой результат:
Результат запросаКлиент Код юр лица Код ТТ Код продукции Дата Цена id Цена пред Маркировка скидки Цена пред кот исполь в расчКлиент1 Код юр лица1 Код ТТ1 SKU1 2014-01-01 100 1 100 0 NULLКлиент1 Код юр лица1 Код ТТ1 SKU1 2014-01-02 80 2 80 1 100Клиент1 Код юр лица1 Код ТТ1 SKU1 2014-01-03 80 3 80 1 80Клиент1 Код юр лица1 Код ТТ1 SKU1 2014-01-04 80 4 80 1 80Клиент1 Код юр лица1 Код ТТ1 SKU1 2014-01-05 100 5 100 0 80Клиент1 Код юр лица1 Код ТТ1 SKU1 2014-01-06 100 6 100 0 100Клиент1 Код юр лица1 Код ТТ1 SKU2 2014-01-01 50 7 50 1 100Клиент1 Код юр лица1 Код ТТ1 SKU2 2014-01-02 100 8 100 0 50Клиент1 Код юр лица1 Код ТТ1 SKU2 2014-01-03 80 9 80 1 100Клиент1 Код юр лица1 Код ТТ1 SKU2 2014-01-04 80 10 80 1 80Клиент1 Код юр лица1 Код ТТ1 SKU2 2014-01-05 100 11 100 0 80Клиент1 Код юр лица1 Код ТТ1 SKU2 2014-01-06 100 12 100 0 100Клиент1 Код юр лица1 Код ТТ2 SKU1 2014-01-01 60 13 60 1 100Клиент1 Код юр лица1 Код ТТ2 SKU1 2014-01-02 100 14 100 0 60Клиент1 Код юр лица1 Код ТТ2 SKU1 2014-01-03 80 15 80 1 100Клиент1 Код юр лица1 Код ТТ2 SKU1 2014-01-04 80 16 80 1 80Клиент1 Код юр лица1 Код ТТ2 SKU1 2014-01-05 100 17 100 0 80Клиент1 Код юр лица1 Код ТТ2 SKU1 2014-01-06 100 18 100 0 100

Если на следующей строке другая группа, то есть другое SKU, другая ТТ, то предыдущую цену и предыдущую маркировку смотреть не нужно. Для этой же строки в поле Маркировка скидки сразу возвращает ноль. Как правильно дописать запрос?

И еще. В поле Цена пред отображается текущая цена, но не предыдущая. Почему так?
...
Рейтинг: 0 / 0
12.04.2018, 11:58
    #39628969
Kopelly
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предыдущее значение вычисляемого поля
ferzmikk,

Код: sql
1.
id=ROW_NUMBER()over(Partition by [Клиент], [Код юр лица], [Код ТТ], [Код продукции] order by  [Дата]) from @Таблица)



Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
FROM
		cte
	INNER JOIN
		t
	ON
		t.id=cte.id+1 and 
		t.[Клиент]=cte.[Клиент] and 
		t.[Код юр лица]=cte.[Код юр лица] and 
		t.[Код ТТ]=cte.[Код ТТ] and 
		t.[Код продукции]=cte.[Код продукции]
	and 
...
Рейтинг: 0 / 0
12.04.2018, 11:59
    #39628970
Kopelly
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Предыдущее значение вычисляемого поля
Еще и быстрее будет выполняться
...
Рейтинг: 0 / 0
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Предыдущее значение вычисляемого поля / 25 сообщений из 46, страница 1 из 2
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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