Я пишу приложение, которое отслеживает просмотры различных элементов во времени, и я немного ударил. Мне нужно получить разницу во взглядах между двумя соседними обновлениями. Обновления идентифицируются с помощью клавиши UNIQUE
, содержащей столбцы time
и id
. Как я смогу это сделать, не выполняя несколько запросов?
SELECT updates.views, (updates.views - <previous views>)
FROM updates JOIN stuff ON stuff.id = stuff.id
WHERE updates.time = '01-01-1970 00:00:00' AND stuff.owner = 'someone'
Это должно работать практически во всех РСУБД:
SELECT
UPD.id,
UPD.views,
(UPD.views - COALESCE(LAST_UPD.views, 0))
FROM
Updates UPD
INNER JOIN Stuff S ON
S.id = UPD.id AND
S.owner = 'someone'
INNER JOIN Updates LAST_UPD ON
LAST_UPD.id = UPD.id AND
LAST_UPD.time < UPD.time
LEFT OUTER JOIN Updates UPD2 ON
UPD2.id = LAST_UPD.id AND
UPD2.time < UPD.time AND
UPD2.time > LAST_UPD.time
WHERE
UPD2.id IS NULL AND
UPD.time = '01-01-1970 00:00:00'
В основном вы говорите: "Дайте мне предыдущее обновление (LAST_UPD.time < UPD.time), для которого нет других обновлений после него и до этого (левое соединение и UPD2.id IS NULL).
UPD2.id IS NULL
говорит о том, что между LAST_UPD
и UPD
не может быть строк. Это не говорит, что столбец должен быть нулем; это говорит о том, что третий JOIN должен провалиться
В Oracle
и PostgreSQL 8.4
:
SELECT views - LAG(views) OVER (ORDER BY time, id)
FROM updates
JOIN stuff
ON stuff.id = updates.stuffid
WHERE updates.time = '01-01-1970 00:00:00'
AND stuff.owner = 'someone'
В MySQL
:
SELECT views - @pviews AS diff,
@pviews := views
FROM (
SELECT @pviews := NULL
) vars
CROSS JOIN
updates
JOIN stuff
ON stuff.id = updates.stuffid
WHERE updates.time = '01-01-1970 00:00:00'
AND stuff.owner = 'someone'
ORDER BY
time, id
Вы можете выбрать предыдущий максимум в подзапросе:
SELECT updates.views
, (updates.views - (
select max(prevupd.views)
from updates prevupd
where prevupd.id <> updates.id
))
FROM updates
JOIN stuff ON stuff.id = stuff.id
WHERE updates.time = '01-01-1970 00:00:00'
AND stuff.owner = 'someone'
Некоторые примеры данных были бы хороши, как предлагает Ларри Лустиг.