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

Откуда:
Сообщений: 539
Добрый день!
Помогите пожалуйста оптимизировать следующий запрос:
IF OBJECT_ID('tempdb..#t') IS NOT NULL DROP TABLE #t
CREATE TABLE #t
(
	[id] INT IDENTITY PRIMARY KEY CLUSTERED,
	[idGoods] INT, 
	[Date] DATETIME
)

INSERT INTO #t
SELECT 1,'2012-01-01'
UNION ALL
SELECT 2,'2012-01-04'
UNION ALL
SELECT 1,'2012-01-05'
UNION ALL
SELECT 1,'2012-01-21'
UNION ALL
SELECT 2,'2012-01-25'
UNION ALL
SELECT 1,'2012-02-07'
UNION ALL
SELECT 1,'2012-02-25'

SELECT 
t.id,t.idGoods
,
( 
	SELECT TOP 1 Date 
	FROM #t ev
	WHERE ev.idGoods = t.IdGoods AND ev.Date < t.Date
	ORDER BY Date
) PrevDate
,t.Date
,
( 
	SELECT TOP 1 Date 
	FROM #t ev
	WHERE ev.idGoods = t.IdGoods AND ev.Date > t.Date
	ORDER BY Date
) NextDate
FROM #t t
ORDER BY [Date]


Итак, имеется таблица #t неких фактов.
у разных IdGoods, в разные даты меняется кол-во, цена и т.п.
Cуть данного запроса определить предыдущий и следующий факт для каждого дня, если они есть конечно же.
В голову приходит, только такой select, возможно есть другие решения.
Если этот запрос не очень, подскажите пожалуста в каком направлении следует двигаться.
Спасибо!
5 авг 13, 14:17    [14664054]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущий и следующий факт  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
1)А что если предыдушую и следующую даты находить через left join с последующей группировкой по t.id,t.idGoods ?
2) Пронумеровать в группе по товару через row_number () потом left join соответственно с предыдущим и следующим членом группы?
3) Если 2012, то lag
5 авг 13, 14:25    [14664111]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущий и следующий факт  [new]
Гость333
Member

Откуда:
Сообщений: 3683
RomanH
в каком направлении следует двигаться.

В направлении LAG/LEAD.
5 авг 13, 14:26    [14664116]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущий и следующий факт  [new]
RomanH
Member

Откуда:
Сообщений: 539
Мистер Хенки
1)А что если предыдушую и следующую даты находить через left join с последующей группировкой по t.id,t.idGoods ?
2) Пронумеровать в группе по товару через row_number () потом left join соответственно с предыдущим и следующим членом группы?
3) Если 2012, то lag


версия сиквела 2012
Попробую пункты 1.2.
Спасибо!
5 авг 13, 14:32    [14664159]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущий и следующий факт  [new]
iap
Member

Откуда: Москва
Сообщений: 47000
RomanH
Мистер Хенки
1)А что если предыдушую и следующую даты находить через left join с последующей группировкой по t.id,t.idGoods ?
2) Пронумеровать в группе по товару через row_number () потом left join соответственно с предыдущим и следующим членом группы?
3) Если 2012, то lag


версия сиквела 2012
Попробую пункты 1.2.
Спасибо!
Вам идеально подходит пункт 3, однако!
5 авг 13, 15:12    [14664511]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущий и следующий факт  [new]
RomanH
Member

Откуда:
Сообщений: 539
iap
RomanH
пропущено...


версия сиквела 2012
Попробую пункты 1.2.
Спасибо!
Вам идеально подходит пункт 3, однако!


Отстаю... к сожалению не могу использовать 2012 редакцию.


Может кому понадобится для 2008. ну вдруг...
;with cte(id,IdGoods,date,rn)
as
(
	select *,
	RANK() OVER(PARTITION BY IdGoods ORDER BY Date ) rn 
	from #t
) 
select t.id, t.IdGoods, p.Date PrevDate ,t.Date, n.Date NextDate 
from cte t
left join cte p on p.rn + 1 = t.rn and p.IdGoods = t.IdGoods
left join cte n on n.rn = t.rn + 1 and n.IdGoods = t.IdGoods
5 авг 13, 15:27    [14664662]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущий и следующий факт  [new]
Cygapb-007
Member

Откуда:
Сообщений: 1677
RomanH
Отстаю... к сожалению не могу использовать 2012 редакцию.

Вот тут: http://sqlfiddle.com - не требуется установка локального MS SQL 2012 :) Все уже установлено, до для вас
5 авг 13, 16:02    [14664963]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущий и следующий факт  [new]
Мистер Хенки
Member

Откуда: канализация
Сообщений: 6615
RomanH,
rank() не подойдет, у него "дыры" в нумерации. dense_rank() или row_number() в зависимости от того, что хотите получить.
5 авг 13, 16:03    [14664973]     Ответить | Цитировать Сообщить модератору
 Re: Предыдущий и следующий факт  [new]
Mnior
Member

Откуда: Кишинёв
Сообщений: 6723
Есть костыль без JOIN. 11690698
5 авг 13, 18:18    [14665797]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить