re: [Sql] получить предыдущую, следующую запись в групповом запросе?

Dasar

в продолжении поста
таблица
objid, value, time
необходимо эффективно выполнить следующий запрос:
по каждому Objid получить последнюю запись, которая шла перед заданным временем
в mssql(начиная с 2005) это делается так

select ObjId, Value, Time From
(
select * row_number over (partition by ObjId order by Time desc) as row_number
from objId_value_time_table
where Time < @selectedTime
) as b
where b.row_number = 1

anatolii

dense_rank не подойдёт?

Dasar

dense_rank не подойдёт?
подойдет - если есть уникальность по Time, но код будет такой же, только вместо row_number будет dense_rank

hprt

Не знаю, эффективнее ли, может даже план совпадать будет, но текст запроса другой - TOP 1 WITH TIES с соотв ORDER BY. Ну и плюс индекс по времени может сильно менять картину

Dasar

но текст запроса другой - TOP 1 WITH TIES с соотв ORDER BY.
полный текст запроса напиши, плиз.
ps
я с with еще не разбирался, поэтому пока не могу прокомментировать твое предложение

hprt

это не WITH (то бишь не CTE) - работает как TOP, но дополнительно захватывает равноценные с точки зрения сортировки результаты.
 
select top 1 with ties
ObjID, Value, Time
from objId_value_time_table
where Time < @selectedTime
order by row_number over (partition by ObjId order by Time desc)

Посмотрел на sysobjects - вроде не быстрее так - вариант с фильтрацией по row_number etc. 13% от общего батча, с TOP 1 - 21% (запустил оба варианта для row_number rank и dense_rank хотя визуально разница неочевидна - может на больших объемах будет разница заметна.
Можно еще посмотреть вариант с группировкой в подзапросе, но думаю он медленнее будет, чем аналитические функции

hprt

Если есть индекс по Time (Time + ObjID) - можно попробовать туда добавить как included columns оставшиеся вытаскиваемые колонки, тогда обращения к самой таблице не будет

Dasar

как included columns
это что такое?

hprt

В общем, это данные, которые не участвуют в построении индекса, но присутствуют в листовых узлах
Оставить комментарий
Имя или ник:
Комментарий: