[Sql] получить предыдущую, следующую запись в групповом запросе?
http://www.oracle-base.com/articles/misc/LagLeadAnalyticFunc...
В MS SQL`е правда это ещё не реализовали вроде, хотя в стандарте есть...
В MS SQL`е правда это ещё не реализовали вроде, хотя в стандарте есть...
select top 1 * from data where time > @prevTimeесли не указана сортировка, то этот запрос вернет "случайную" запись
а в PL вообще вернёт ошибку
согласен. должно быть так
select top 1 * from data where time > @prevTime order by time
Если оракловая база, то ссылку на LAG и LEAD тебе дали, если MS SQL и др., то эффективно в самом запросе не вернуть, однако можно быстро получить нужную строку на клиенте, например.
SELECT T1.*
FROM T1
WHERE
[Time] =
(
SELECT MAX([Time])
FROM T1
WHERE [Time] < '10-01-2001'
)
SELECT T1.*
FROM T1
INNER JOIN
(
SELECT ObjectId, MAX([Time]) AS MaxTime
FROM T1
WHERE [Time] < '10-01-2001'
GROUP BY ObjectId
) T2
ON T1.ObjectId = T2.ObjectId
AND T1.[Time] = T2.MaxTime
однако можно быстро получить нужную строку на клиентенасколько я понял, на клиенте требуется получить весь набор строк, это сделать быстрее, чем лазить за каждой строкой в базу.
даже при наличии подходящего индекса?
имхо, такой запрос обычно раскрывается в два пробега по индексу, в отличии от order by
или я ошибаюсь?
запрос неправильный (так же как и предыдущий одинночный) так как для каждого объекта может вернуть несколько записей, хотя требовалась только по одной
имхо, такой запрос обычно раскрывается в два пробега по индексу, в отличии от order byпри наличии индекса по Time, планы запросов совпадают.
или я ошибаюсь?
запрос неправильный (так же как и предыдущий одинночный) так как для каждого объекта может вернуть несколько записей, хотя требовалась только по однойимхо, странное бизнес-требование — выбор произвольной ("случайной") записи из множества.
SELECT T1.*
FROM T1
INNER JOIN
(
SELECT ObjectId, MAX([Time]) AS MaxTime, MAX([Value]) AS MaxValue
FROM T1
WHERE [Time] < '10-01-2001'
GROUP BY ObjectId
) T2
ON T1.ObjectId = T2.ObjectId
AND T1.[Time] = T2.MaxTime
AND T1.[Value] = T2.MaxValue
я бы вообще через курсор сделал, пробежаться по всем строчкам и полученные данные загнать во временную таблицу
нормальное бизнес-требование - выбрать максимальную запись.
и опять же нормальное требование - что нет уникальности по тому полю, по которому берется максимум.
выбрать максимальную запись ...если требуется выбрать одну запись и нет уникальности, то придется выбирать "случайную" запись
нет уникальности по тому полю, по которому берется максимум
согласен, надо брать случайную
но неправильно брать несколько
T1.ObjectId = T2.ObjectId
AND T1.[Time] = T2.MaxTime
AND T1.[Value] = T2.MaxValue
и неправильно требовать наличие индекса по objectId, time и value.
неправильно - в том смысле, что в общем случае хотелось бы обойтись без поиска мифического доп. поля на который повешен такой подходящий для нас индекс.
Оставить комментарий
Dasar
Как в sql эффективно получать предыдущую, следующую запись в групповом запросе?при одиночном запросе все понятно - делаем отсечку по rownum/top.
а как быть в групповом запросе? например, когда надо получить следующие записи для целого набора.
зы
конкретная постановка
таблица
objid, value, time
необходимо эффективно выполнить следующий запрос:
по каждому Objid получить последнюю запись, которая шла перед заданным временем
ззы
задача модельная: т.е. в первую очередь хочется научиться решать задачи схожего класса.