I'm using Oracle PL/SQL.
I have a timestamped table T, and I want to set a row's value for column A to be the same as that of the previous row, if they're sorted by columns B and Timestamp, provided that the timestamps are not different by more than 45 seconds.
In pseudocode, it's something like:
UPDATE T t_curr
SET A =
(SELECT A
FROM T t_prev
INNER JOIN t_curr
ON (t_prev is the row right before t_curr, when you sort by B and Timestamp)
AND t_curr.Timestamp - t_prev.Timestamp < 45
)
I tried this:
UPDATE T t_curr
SET A =
(SELECT A
FROM T t_prev
INNER JOIN t_curr
ON RANK (t_curr)
OVER (B, Timestamp)
= 1 + RANK (t_prev)
OVER (B, Timestmap)
AND t_curr.Timestamp - t_prev.Timestamp < 45
)
But I got:
Error(38,16): PL/SQL: ORA-00934: group function is not allowed here
pointing at the first instance of RANK.
What did I do wrong, and how do I get this right?
Can you try something like this:
What you can do is.
This requires that the column you want to update is null, unless you want to update all of them.
You could try (might need some tweaking to get it right, but the idea is two identical ordered subqueries joined by offset rownumbers)
Try using a merge statement. Not sure it quite does what you want but it should work. Unfortunately the insert clause is necessary) but shouldn't ever be called.
And another option... doesn't quite do what do want because it ignores the requirement to sort on B but it might give you something to think about.... Without table definitions and things it was a little hard to get a handle on exactly what was required.
Edit: on reading the question again, it looks like your syntax is wrong. Group functions (lead/lag/rank etc) can only appear in the select list or the order by clause. They are evaluated after the joins, where, group by and having clauses. So something like what is shown below should work.