I have a table from which I need to calculate the number of times intent_level
changes for each id
.
Sample Table format :
x
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.