Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Предыдущее значение вычисляемого поля  [new]
ferzmikk
Member

Откуда:
Сообщений: 2220
Здравствуйте!

Есть SQL-запрос.
+SQL-запрос
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-Запрос
	(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 не работает во вложенном запросе. В рабочем коде используются табличные выражения и вложенные запросы. Как можно обойти эту проблему?
9 апр 18, 15:47    [21324029]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущее значение вычисляемого поля  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 21242
ferzmikk
Как вытягивать предыдущее значение вычисляемого поля?
LEAD()

ferzmikk
Order By не работает во вложенном запросе.
ORDER BY в промежуточных итогах используется только в том случае, когда влияет на список записей выходного набора. Без ограничения количества возвращаемых записей простая сортировка на набор не влияет - а потому игнорируется.
9 апр 18, 16:12    [21324121]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущее значение вычисляемого поля  [new]
ferzmikk
Member

Откуда:
Сообщений: 2220
Akina
ferzmikk
Как вытягивать предыдущее значение вычисляемого поля?
LEAD()

LEAD вытягивает из последующей строки, а надо из предыдущей. А также по текущей строке при расчете вычисляемого поля [Маркировка скидки] нужно вытянуть рассчитанное значение этого же поля предыдущей строки.
9 апр 18, 16:48    [21324231]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущее значение вычисляемого поля  [new]
ferzmikk
Member

Откуда:
Сообщений: 2220
Akina
ferzmikk
Order By не работает во вложенном запросе.
ORDER BY в промежуточных итогах используется только в том случае, когда влияет на список записей выходного набора. Без ограничения количества возвращаемых записей простая сортировка на набор не влияет - а потому игнорируется.

Поскольку во вложенном запросе я использую оконную функция Lag, то актуально делать сортировку, если я не ошибаюсь.
9 апр 18, 16:52    [21324241]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущее значение вычисляемого поля  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 21242
ferzmikk
Поскольку во вложенном запросе я использую оконную функция Lag, то актуально делать сортировку, если я не ошибаюсь.
LAG() имеет свой собственный класс ORDER BY и не зависит от внешнего.
9 апр 18, 16:57    [21324253]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущее значение вычисляемого поля  [new]
ferzmikk
Member

Откуда:
Сообщений: 2220
ferzmikk
Akina
пропущено...
LEAD()

LEAD вытягивает из последующей строки, а надо из предыдущей. А также по текущей строке при расчете вычисляемого поля [Маркировка скидки] нужно вытянуть рассчитанное значение этого же поля предыдущей строки.

А тут как?
9 апр 18, 17:24    [21324315]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущее значение вычисляемого поля  [new]
Дедушка
Member

Откуда: Город трёх революций
Сообщений: 5115
ferzmikk
А тут как?
делать в два прохода
9 апр 18, 17:53    [21324386]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущее значение вычисляемого поля  [new]
ferzmikk
Member

Откуда:
Сообщений: 2220
Тут расчет получается последовательным как в excel.

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

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

Как написать запрос?

К сообщению приложен файл. Размер - 14Kb
9 апр 18, 19:50    [21324586]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущее значение вычисляемого поля  [new]
court
Member

Откуда:
Сообщений: 2373
ferzmikk
Как написать запрос?
"рекурсивно",
в смысле рекурсивный запрос :)
9 апр 18, 20:11    [21324602]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущее значение вычисляемого поля  [new]
court
Member

Откуда:
Сообщений: 2373
court
ferzmikk
Как написать запрос?
"рекурсивно",
в смысле рекурсивный запрос :)

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
9 апр 18, 20:30    [21324623]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущее значение вычисляемого поля  [new]
ferzmikk
Member

Откуда:
Сообщений: 2220
court,

Спасибо, буду разбирать!
9 апр 18, 20:37    [21324642]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущее значение вычисляемого поля  [new]
invm
Member

Откуда: Москва
Сообщений: 9827
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;
?
9 апр 18, 22:08    [21324767]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущее значение вычисляемого поля  [new]
ferzmikk
Member

Откуда:
Сообщений: 2220
invm,

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

+
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
10 апр 18, 07:50    [21325094]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущее значение вычисляемого поля  [new]
ferzmikk
Member

Откуда:
Сообщений: 2220
court,

При таком запросе
+
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
10 апр 18, 08:09    [21325105]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущее значение вычисляемого поля  [new]
ferzmikk
Member

Откуда:
Сообщений: 2220
court,

И еще, при использовании рекурсии, когда много строк, то запрос намного дольше выполянется. Возможно ли как то ускорить?
10 апр 18, 08:11    [21325107]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущее значение вычисляемого поля  [new]
ferzmikk
Member

Откуда:
Сообщений: 2220
ferzmikk
court,

И еще, при использовании рекурсии, когда много строк, то запрос намного дольше выполянется. Возможно ли как то ускорить?

165 строк - 2 мин 36 сек
10 апр 18, 08:44    [21325139]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущее значение вычисляемого поля  [new]
court
Member

Откуда:
Сообщений: 2373
ferzmikk
court,

При таком запросе
+
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
это исправь (желтым выделено)
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


[Цена пред которая используется в расчете] - это для понимания, что там вообще происходит, если нужно
10 апр 18, 09:57    [21325334]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущее значение вычисляемого поля  [new]
ferzmikk
Member

Откуда:
Сообщений: 2220
court,

В условном примере правильно работает, а в рабочем - не правильно. Не могу понять.

К сообщению приложен файл. Размер - 15Kb
10 апр 18, 12:19    [21325985]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущее значение вычисляемого поля  [new]
ferzmikk
Member

Откуда:
Сообщений: 2220


К сообщению приложен файл. Размер - 47Kb
10 апр 18, 12:30    [21326058]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущее значение вычисляемого поля  [new]
ferzmikk
Member

Откуда:
Сообщений: 2220
ferzmikk
court,

В условном примере правильно работает, а в рабочем - не правильно. Не могу понять.

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

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

и из за этого неправильно сортировался, следовательно, неправильно маркировались.
10 апр 18, 12:32    [21326069]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущее значение вычисляемого поля  [new]
ferzmikk
Member

Откуда:
Сообщений: 2220
Из за рекурсии подтормаживает сильно. Возможно ли как то ускорить выгрузку?
10 апр 18, 14:31    [21326669]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущее значение вычисляемого поля  [new]
ferzmikk
Member

Откуда:
Сообщений: 2220
ferzmikk
Из за рекурсии подтормаживает сильно. Возможно ли как то ускорить выгрузку?

65000 строк. Обрабатывает более 2 часов.

Может быть в ON еще связку указать?
10 апр 18, 16:24    [21327157]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущее значение вычисляемого поля  [new]
ferzmikk
Member

Откуда:
Сообщений: 2220
Обнаружил не учтенный момент.
+SQL-запрос
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, другая ТТ, то предыдущую цену и предыдущую маркировку смотреть не нужно. Для этой же строки в поле Маркировка скидки сразу возвращает ноль. Как правильно дописать запрос?

И еще. В поле Цена пред отображается текущая цена, но не предыдущая. Почему так?
12 апр 18, 11:42    [21332597]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущее значение вычисляемого поля  [new]
Kopelly
Member

Откуда: Красноярск
Сообщений: 291
ferzmikk,

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


FROM
		cte
	INNER JOIN
		t
	ON
		t.id=cte.id+1 and 
		t.[Клиент]=cte.[Клиент] and 
		t.[Код юр лица]=cte.[Код юр лица] and 
		t.[Код ТТ]=cte.[Код ТТ] and 
		t.[Код продукции]=cte.[Код продукции]
	and 
12 апр 18, 11:58    [21332662]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущее значение вычисляемого поля  [new]
Kopelly
Member

Откуда: Красноярск
Сообщений: 291
Еще и быстрее будет выполняться
12 апр 18, 11:59    [21332665]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить