I have a table from which I need to calculate the number of times intent_level changes for each id.
Sample Table format :
id | start_time | intent_level ----+------------+-------------- 1 | 2 | status 1 | 3 | status 1 | 1 | 1 | 4 | category 2 | 5 | status 2 | 8 | 2 | 7 | status
I couldn’t figure out how to loop through array_agg and compare consecutive elements. Below I tried using array_agg, but then I don’t know how to loop through it and compare consecutive elements.
select id, array_agg (intent_level ORDER BY start_time) FROM temp.chats GROUP BY id;
which gives output :
id | array_agg
----+-----------------------------
1 | {"",status,status,category}
2 | {status,status,""}
Desired output is :
id | array_agg ----+----------------------------- 1 | 2 2 | 1
2 (since value changes from "" to status(1 to 2) and status to category(3 to 4))
1 (since value changes from status to ""(2 to 3))
CREATE AND INSERT QUERIES :
create table temp.chats (
id varchar(5),
start_time varchar(5),
intent_level varchar(20)
);
insert into temp.chats values
('1', '2', 'status'),
('1', '3', 'status'),
('1', '1', ''),
('1', '4', 'category'),
('2', '5', 'status'),
('2', '8', ''),
('2', '7', 'status');
Advertisement
Answer
Use lag() and aggregate:
select id, count(*)
from (select c.*,
lag(intent_level) over (partition by id order by start_time) as prev_intent_level
from temp.chats c
) c
where prev_intent_level is distinct from intent_level
group by id;
Here is a db<>fiddle.
Arrays seem quite unnecessary for this.