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

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

Есть SQL-запрос, который для каждого ТТ+SKU обращается к предыдущему значению с помощью рекурсии.
+SQL-запрос
DECLARE @Таблица table(		
	[Код ТТ] varchar(8),	
	[Код продукции] varchar(8),
	[Дата] date,
	[Отгрузка] integer,	
	[ID] INTEGER)	
;

INSERT INTO
  @Таблица
VALUES 
('Код ТТ1','SKU1', '01.01.2014', 100, 1),
('Код ТТ1','SKU1', '02.01.2014', 110, 2),
('Код ТТ1','SKU1', '03.02.2014', 120, 3),
('Код ТТ1','SKU1', '04.02.2014', 130, 4),
('Код ТТ1','SKU2', '01.02.2014', 100, 1),
('Код ТТ1','SKU2', '02.02.2014', 110, 2),
('Код ТТ1','SKU2', '03.03.2014', 120, 3),
('Код ТТ1','SKU2', '04.03.2014', 130, 4)
;
WITH
	cte AS (
		SELECT
			*,			
			[Предыдущая отгрузка]=cast(null as integer)
		FROM
			@Таблица
		WHERE
			[ID]  = 1			
	UNION ALL	
		SELECT
			Таб.*,			
			cte.[Отгрузка]	
		FROM
			@Таблица Таб
		inner join
			cte
		ON
			Таб.[ID] = cte.[ID] + 1	
			AND 
			Таб.[Код ТТ] = cte.[Код ТТ]
			AND 
			Таб.[Код продукции] = cte.[Код продукции]
	)

SELECT
	[Код ТТ],	
	[Код продукции],
	[Дата],
	[Отгрузка]	
	[ID],
	[Предыдущая отгрузка]
FROM
	cte
ORDER BY	
	[Код ТТ],
	[Код продукции],
	[ID]

1. Добавляю поле [Предыдущая отгрузка]. Скажите, почему не отображается поле отгрузка?
2. Как сделать так, чтобы для каждого ТТ+SKU
- отбирались с ID = 1, если это не январь
- отбирались с ID = 2, если при ID=1 это январь.

Результат должен быть таким
Код ТТ Код продукции Дата Отгрузка IDПредыдущая отгрузка
Код ТТ1 SKU1 2014-01-01 100 1NULL
Код ТТ1 SKU1 2014-01-02 110 2NULL
Код ТТ1 SKU1 2014-02-03 120 3110
Код ТТ1 SKU1 2014-02-04 130 4120
Код ТТ1 SKU2 2014-02-01 100 1NULL
Код ТТ1 SKU2 2014-02-02 110 2100
Код ТТ1 SKU2 2014-03-03 120 3110
Код ТТ1 SKU2 2014-03-04 130 4120
3 май 18, 15:57    [21385006]     Ответить | Цитировать Сообщить модератору
 Re: SQL-запрос. Вопрос по рекурсии  [new]
Kopelly
Member

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

Так и пиши:
( ID = 1 and Month([Дата])>1) or
( ID = 2 and Month([Дата])=1)
3 май 18, 16:38    [21385254]     Ответить | Цитировать Сообщить модератору
 Re: SQL-запрос. Вопрос по рекурсии  [new]
Glebanski
Member

Откуда: Msk ->NL
Сообщений: 308
ferzmikk,

Что еще за адская ересь с рекурсией, когда LAG просто напрашивается?
select 
	[Код ТТ],		[Код продукции],	[Дата],	[Отгрузка]	,	[ID],
	lag(case when month([Дата]) =1  then NULL else  [Отгрузка] end) over (partition by [Код ТТ],		[Код продукции] order by [Дата]) as [Предыдущая отгрузка]
	from 
	@Таблица


Далее сам
3 май 18, 16:47    [21385285]     Ответить | Цитировать Сообщить модератору
 Re: SQL-запрос. Вопрос по рекурсии  [new]
Glebanski
Member

Откуда: Msk ->NL
Сообщений: 308
ferzmikk,

Я мог ТЗ недопонять, так что возможно надо через LAG номер месяца вытаскивать, а не Отгрузку. И если он равен 1, то занулять поле
3 май 18, 18:20    [21385600]     Ответить | Цитировать Сообщить модератору
 Re: SQL-запрос. Вопрос по рекурсии  [new]
ferzmikk
Member

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

Так и пиши:
( ID = 1 and Month([Дата])>1) or
( ID = 2 and Month([Дата])=1)

+SQL-Запрос
DECLARE @Таблица table(		
	[Код ТТ] varchar(8),	
	[Код продукции] varchar(8),
	[Дата] date,
	[Отгрузка] integer,	
	[ID] INTEGER)	
;

INSERT INTO
  @Таблица
VALUES 
('Код ТТ1','SKU1', '01.01.2014', 100, 1),
('Код ТТ1','SKU1', '02.01.2014', 110, 2),
('Код ТТ1','SKU1', '03.02.2014', 120, 3),
('Код ТТ1','SKU1', '04.02.2014', 130, 4),
('Код ТТ1','SKU2', '01.02.2014', 100, 1),
('Код ТТ1','SKU2', '02.02.2014', 110, 2),
('Код ТТ1','SKU2', '03.03.2014', 120, 3),
('Код ТТ1','SKU2', '04.03.2014', 130, 4),
('Код ТТ2','SKU1', '01.01.2014', 100, 1),
('Код ТТ2','SKU1', '02.01.2014', 110, 2),
('Код ТТ2','SKU1', '03.02.2014', 120, 3),
('Код ТТ2','SKU1', '04.03.2014', 130, 4)
;
WITH
	cte AS (
		SELECT
			*,			
			[Предыдущая отгрузка]=cast(null as integer)
		FROM
			@Таблица
		WHERE
			--[ID]  = 1
			([ID] = 1 and Month([Дата])>1) or ( [ID] = 2 and Month([Дата])=1)
	UNION ALL	
		SELECT
			Таб.*,			
			cte.[Отгрузка]	
		FROM
			@Таблица Таб
		inner join
			cte
		ON
			Таб.[ID] = cte.[ID] + 1	
			AND 
			Таб.[Код ТТ] = cte.[Код ТТ]
			AND 
			Таб.[Код продукции] = cte.[Код продукции]
	)

SELECT
	[Код ТТ],	
	[Код продукции],
	[Дата],
	[Отгрузка]	
	[ID],
	[Предыдущая отгрузка]
FROM
	cte
ORDER BY	
	[Код ТТ],
	[Код продукции],
	[ID]

Выдает такой результат
Код ТТ Код продукции Дата ID Предыдущая отгрузка
Код ТТ1 SKU1 2014-01-02 110 NULL
Код ТТ1 SKU1 2014-02-03 120 110
Код ТТ1 SKU1 2014-02-04 130 120
Код ТТ1 SKU2 2014-02-01 100 NULL
Код ТТ1 SKU2 2014-02-02 110 100
Код ТТ1 SKU2 2014-03-03 120 110
Код ТТ1 SKU2 2014-03-04 130 120
Код ТТ2 SKU1 2014-01-02 110 NULL
Код ТТ2 SKU1 2014-02-03 120 110
Код ТТ2 SKU1 2014-03-04 130 120


Не пойму. Почему вместо поля [ID] отображается отгрузка и самого [ID] нету. Почему так? Как правильно написать?
3 май 18, 21:42    [21385901]     Ответить | Цитировать Сообщить модератору
 Re: SQL-запрос. Вопрос по рекурсии  [new]
ferzmikk
Member

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

Что еще за адская ересь с рекурсией, когда LAG просто напрашивается?
select 
	[Код ТТ],		[Код продукции],	[Дата],	[Отгрузка]	,	[ID],
	lag(case when month([Дата]) =1  then NULL else  [Отгрузка] end) over (partition by [Код ТТ],		[Код продукции] order by [Дата]) as [Предыдущая отгрузка]
	from 
	@Таблица


Далее сам


Glebanski
ferzmikk,

Я мог ТЗ недопонять, так что возможно надо через LAG номер месяца вытаскивать, а не Отгрузку. И если он равен 1, то занулять поле

Есть рабочий код и он большой. Чтобы легко было проблему понять и быстро найти решение - упростил код. А так это продолжение Предыдущее значение вычисляемого поля
3 май 18, 21:48    [21385906]     Ответить | Цитировать Сообщить модератору
 Re: SQL-запрос. Вопрос по рекурсии  [new]
Kopelly
Member

Откуда: Красноярск
Сообщений: 289
ferzmikk
Не пойму. Почему вместо поля [ID] отображается отгрузка и самого [ID] нету. Почему так? Как правильно написать?

Запятую пропустил.
SELECT
	[Код ТТ],	
	[Код продукции],
	[Дата],
	[Отгрузка]	,
	[ID],
	[Предыдущая отгрузка]
FROM
4 май 18, 04:53    [21386113]     Ответить | Цитировать Сообщить модератору
 Re: SQL-запрос. Вопрос по рекурсии  [new]
LameUser
Member

Откуда:
Сообщений: 2028
Как увидел русские названия колонок и таблицы хотел закрыть топик нафиг сходу.
Сделал усилие над собой, скажи спасибо, что сегодня пятница.

Glebanski тебе правильно все сказал.
Объяснять не буду, надеюсь сам допрешь где у тебя ошибка еще до запроса к твоей таблице.

DECLARE @t table
(		
	[TTCode] varchar(8),	
	[ProductCode] varchar(8),
	[Date] date,
	[Shipping] integer,	
	[ID] INTEGER
)	


INSERT INTO
  @t
VALUES 
--('Код ТТ1','SKU1', '01.01.2014', 100, 1),
--('Код ТТ1','SKU1', '02.01.2014', 110, 2),
--('Код ТТ1','SKU1', '03.02.2014', 120, 3),
--('Код ТТ1','SKU1', '04.02.2014', 130, 4),
--('Код ТТ1','SKU2', '01.02.2014', 100, 1),
--('Код ТТ1','SKU2', '02.02.2014', 110, 2),
--('Код ТТ1','SKU2', '03.03.2014', 120, 3),
--('Код ТТ1','SKU2', '04.03.2014', 130, 4)

('Код ТТ1','SKU1', '01.01.2014', 100, 1),
('Код ТТ1','SKU1', '01.02.2014', 110, 2),
('Код ТТ1','SKU1', '02.03.2014', 120, 3),
('Код ТТ1','SKU1', '02.04.2014', 130, 4),
('Код ТТ1','SKU2', '02.01.2014', 100, 1),
('Код ТТ1','SKU2', '02.02.2014', 110, 2),
('Код ТТ1','SKU2', '03.03.2014', 120, 3),
('Код ТТ1','SKU2', '03.04.2014', 130, 4)

select *, lag(shipping) over (partition by [TTCode], ProductCode order by date), month(date) monthForChecking
from @t
where month(date) > 1 OR  (month (date) = 1 and ID > 1)
4 май 18, 07:44    [21386160]     Ответить | Цитировать Сообщить модератору
 Re: SQL-запрос. Вопрос по рекурсии  [new]
ferzmikk
Member

Откуда:
Сообщений: 2061
LameUser
Как увидел русские названия колонок и таблицы хотел закрыть топик нафиг сходу.
Я специально использую русские буквы, чтобы код легко читался и быстро решение получить.
Сделал усилие над собой, скажи спасибо, что сегодня пятница.
Спасибо большое!
Glebanski тебе правильно все сказал.
Объяснять не буду, надеюсь сам допрешь где у тебя ошибка еще до запроса к твоей таблице.
Да, разобрал.
4 май 18, 07:59    [21386173]     Ответить | Цитировать Сообщить модератору
 Re: SQL-запрос. Вопрос по рекурсии  [new]
Дед-Папыхтет
Member [заблокирован]

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

https://www.sql.ru/blogs/kab/1590
4 май 18, 08:11    [21386188]     Ответить | Цитировать Сообщить модератору
 Re: SQL-запрос. Вопрос по рекурсии  [new]
ferzmikk
Member

Откуда:
Сообщений: 2061
ferzmikk
LameUser
Как увидел русские названия колонок и таблицы хотел закрыть топик нафиг сходу.
Я специально использую русские буквы, чтобы код легко читался и быстро решение получить

А какой риск если использовать русские буквы?
4 май 18, 09:32    [21386321]     Ответить | Цитировать Сообщить модератору
 Re: SQL-запрос. Вопрос по рекурсии  [new]
LameUser
Member

Откуда:
Сообщений: 2028
ferzmikk
ferzmikk
пропущено...
Я специально использую русские буквы, чтобы код легко читался и быстро решение получить

А какой риск если использовать русские буквы?


Риска нет, it just выглядит funny когда смешиваешь two languages в одном месте.
4 май 18, 09:41    [21386376]     Ответить | Цитировать Сообщить модератору
 Re: SQL-запрос. Вопрос по рекурсии  [new]
Посетитель
Member

Откуда:
Сообщений: 1209
LameUser
Риска нет


еще как есть :)
Вам просто не доводилось встречать русские буквы посреди английского слова в коде. и наоборот

вот вам пример вполне работающего кода, несмотря на русскую "а" в середине слова.
declare @Vаl int
select @Vаl  = 123
select @Vаl 



и при попытке добавить новые строки без копипаста названия переменной вы вдруг словите Must declare the scalar variable

соответственно, чем чаще приходится переключаться между раскладками, тем выше риск реализовать такое внезапное творчество
4 май 18, 09:47    [21386403]     Ответить | Цитировать Сообщить модератору
 Re: SQL-запрос. Вопрос по рекурсии  [new]
LameUser
Member

Откуда:
Сообщений: 2028
Посетитель
LameUser
Риска нет

вот вам пример вполне работающего кода, несмотря на русскую "а" в середине слова.
declare @Vаl int



Я бы за это публичную люстрацию устраивал :)
А вообще русский язык в кодировании - это автору надо 1с осваивать ^^.
4 май 18, 10:42    [21386632]     Ответить | Цитировать Сообщить модератору
 Re: SQL-запрос. Вопрос по рекурсии  [new]
ferzmikk
Member

Откуда:
Сообщений: 2061
LameUser
А вообще русский язык в кодировании - это автору надо 1с осваивать ^^.
Раньше в 1С 8.1 и 8.2 программировал :-)
4 май 18, 10:54    [21386682]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить