I have a table with two columns like:
CREATE TABLE actions (
action_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
"action" text NOT NULL
);
and the following data in it:
action_time | action
----------------------------+--------
2016-12-30 14:12:33.353269 | a
2016-12-30 14:12:38.536818 | b
2016-12-30 14:12:43.305001 | a
2016-12-30 14:12:49.432981 | a
2016-12-30 14:12:53.536397 | b
2016-12-30 14:12:57.449101 | b
2016-12-30 14:13:01.592785 | a
2016-12-30 14:13:06.192907 | b
2016-12-30 14:13:11.249181 | b
2016-12-30 14:13:13.690897 | b
(10 rows)
You can assume that there are no duplicate values in the action_time column.
How can I count the number of same actions in a row that were made starting from the last action?
There is no limit on the number of same actions in a row, and any action can be the last one. Also, there is no limit on the variety of different actions: I used just two to simplify the example data.
For this example data I expect the result to be 3. This is because the last action was "b" and it occurred 3 times in a row.
I think the solution can be achieved combining window functions and the WITH RECURSIVE
clause, but I have no idea how to do it.
This should do it.
SELECT COUNT(*)
FROM actions
WHERE action_time > (
SELECT action_time
FROM actions
WHERE action <> (SELECT action FROM actions ORDER BY action_time DESC LIMIT 1)
ORDER BY action_time DESC LIMIT 1);
The inner most query
SELECT action FROM actions ORDER BY action_time DESC LIMIT 1
determines the last action.
The query
SELECT action_time
FROM actions
WHERE action <> (SELECT action FROM actions ORDER BY action_time DESC LIMIT 1)
ORDER BY action_time DESC LIMIT 1
finds the last row with a different action.
The outermost query finds all rows after that row.
I added a little twist to the classic gaps-and-islands solution.
Notice how the ROW_NUMBER functions use descending ORDER BY.
select count(*)
from (select
action
,row_number() over ( order by action_time desc) as rn
,row_number() over (partition by action order by action_time desc) as rn_action
from mytab
) t
group by action
,rn - rn_action
having min(rn) = 1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With