Prueba esto: datos
create table chats
(
chat_id int not null,
user_name text not null,
log_id int not null primary key,
created_on timestamp not null,
message text not null
);
insert into chats(chat_id, user_name, log_id, created_on, message)
values(1, 'john', 20, '1/1/11 3:00:00', 'Hello'),
(1, 'john',21, '1/1/11 3:00:23', 'Anyone there?'),
(1, 'susan',22, '1/1/11 3:00:43', 'Hello!'),
(1, 'susan', 23, '1/1/11 3:00:53', 'What''s up?'),
(1, 'john', 24, '1/1/11 3:01:02', 'Not much'),
(1, 'susan', 25, '1/1/11 3:01:08', 'Cool')
muestra:
select c.*, 'x', next.*
from chats c
left join chats next on next.log_id = c.log_id + 1
order by c.log_id
de salida:
chat_id | user_name | log_id | created_on | message | ?column? | chat_id | user_name | log_id | created_on | message
---------+-----------+--------+---------------------+---------------+----------+---------+-----------+--------+---------------------+---------------
1 | john | 20 | 2011-01-01 03:00:00 | Hello | x | 1 | john | 21 | 2011-01-01 03:00:23 | Anyone there?
1 | john | 21 | 2011-01-01 03:00:23 | Anyone there? | x | 1 | susan | 22 | 2011-01-01 03:00:43 | Hello!
1 | susan | 22 | 2011-01-01 03:00:43 | Hello! | x | 1 | susan | 23 | 2011-01-01 03:00:53 | What's up?
1 | susan | 23 | 2011-01-01 03:00:53 | What's up? | x | 1 | john | 24 | 2011-01-01 03:01:02 | Not much
1 | john | 24 | 2011-01-01 03:01:02 | Not much | x | 1 | susan | 25 | 2011-01-01 03:01:08 | Cool
1 | susan | 25 | 2011-01-01 03:01:08 | Cool | x | | | | |
La agrupación:
select c.*, 'x', next.*, count(case when next.user_name is null or next.user_name <> c.user_name then 1 end) over(order by c.log_id)
from chats c
left join chats next on next.log_id + 1 = c.log_id
order by c.log_id
Salida:
chat_id | user_name | log_id | created_on | message | ?column? | chat_id | user_name | log_id | created_on | message | count
---------+-----------+--------+---------------------+---------------+----------+---------+-----------+--------+---------------------+---------------+-------
1 | john | 20 | 2011-01-01 03:00:00 | Hello | x | | | | | | 1
1 | john | 21 | 2011-01-01 03:00:23 | Anyone there? | x | 1 | john | 20 | 2011-01-01 03:00:00 | Hello | 1
1 | susan | 22 | 2011-01-01 03:00:43 | Hello! | x | 1 | john | 21 | 2011-01-01 03:00:23 | Anyone there? | 2
1 | susan | 23 | 2011-01-01 03:00:53 | What's up? | x | 1 | susan | 22 | 2011-01-01 03:00:43 | Hello! | 2
1 | john | 24 | 2011-01-01 03:01:02 | Not much | x | 1 | susan | 23 | 2011-01-01 03:00:53 | What's up? | 3
1 | susan | 25 | 2011-01-01 03:01:08 | Cool | x | 1 | john | 24 | 2011-01-01 03:01:02 | Not much | 4
(6 rows)
El resultado agrupado:
with grouped_result as
(
select c.log_id, c.user_name, count(case when next.user_name is null or next.user_name <> c.user_name then 1 end) over(order by c.log_id) as the_grouping
from chats c
left join chats next on next.log_id + 1 = c.log_id
order by c.log_id
)
select user_name, max(log_id) as last_chat_of_each_user
from grouped_result
group by the_grouping
,user_name
order by last_chat_of_each_user
de salida:
user_name | last_chat_of_each_user
-----------+------------------------
john | 21
susan | 23
john | 24
susan | 25
(4 rows)
de Chat y respuestas:
with grouped_result as
(
select c.log_id, c.user_name, count(case when next.user_name is null or next.user_name <> c.user_name then 1 end) over(order by c.log_id) as the_grouping
from chats c
left join chats next on next.log_id + 1 = c.log_id
order by c.log_id
),
last_chats as
(
select user_name as responded_to, max(log_id) as last_chat_of_each_user
from grouped_result
group by the_grouping
,responded_to
)
select lc.responded_to, lc.last_chat_of_each_user as responded_to_log_id, lc_the_chat.created_on as responded_to_timestamp, 'x', answered_by.user_name as responded_by, answered_by.created_on as response_created_on
from last_chats lc
join chats lc_the_chat on lc_the_chat.log_id = lc.last_chat_of_each_user
join chats answered_by on answered_by.log_id = lc.last_chat_of_each_user + 1
order by lc.last_chat_of_each_user
Salida: tiempo de respuesta promedio
responded_to | responded_to_log_id | responded_to_timestamp | ?column? | responded_by | response_created_on
--------------+---------------------+------------------------+----------+--------------+---------------------
john | 21 | 2011-01-01 03:00:23 | x | susan | 2011-01-01 03:00:43
susan | 23 | 2011-01-01 03:00:53 | x | john | 2011-01-01 03:01:02
john | 24 | 2011-01-01 03:01:02 | x | susan | 2011-01-01 03:01:08
(3 rows)
de chat:
with grouped_result as
(
select c.log_id, c.user_name, count(case when next.user_name is null or next.user_name <> c.user_name then 1 end) over(order by c.log_id) as the_grouping
from chats c
left join chats next on next.log_id + 1 = c.log_id
order by c.log_id
),
last_chats as
(
select user_name as responded_to, max(log_id) as last_chat_of_each_user
from grouped_result
group by the_grouping
,responded_to
),
responses as
(
select lc.responded_to, lc.last_chat_of_each_user as responded_to_log_id, lc_the_chat.created_on as responded_to_timestamp, answered_by.user_name as responded_by, answered_by.created_on as response_created_on
from last_chats lc
join chats lc_the_chat on lc_the_chat.log_id = lc.last_chat_of_each_user
join chats answered_by on answered_by.log_id = lc.last_chat_of_each_user + 1
order by lc.last_chat_of_each_user
)
select responded_by, responded_to, sum(response_created_on - responded_to_timestamp), count(*), avg(response_created_on - responded_to_timestamp) as average_response_to_person
from responses
group by responded_by, responded_to
Salida:
responded_by | responded_to | sum | count | average_response_to_person
--------------+--------------+----------+-------+----------------------------
susan | john | 00:00:26 | 2 | 00:00:13
john | susan | 00:00:09 | 1 | 00:00:09
(2 rows)
Will trabajar fuera de la caja en PostgreSQL. Para que funcione en el Servidor Sql, simplemente cambie el response_created_on - responded_to_timestamp
a la construcción correspondiente Sql Server DATEDIFF (no puedo recordar la parte superior de mi cabeza ¿cuál es el DATEDIFF por segundos)
mucho más fácil hacerlo establece en función con '' lag' y lead' creo. [Vote por eso aquí] (https://connect.microsoft.com/SQLServer/feedback/details/254388/over-clause-enhancement-request-lag-and-lead-functions) –
¿Existe un límite en el número de usuarios dentro de un contexto ChatID? es decir, para un solo ChatID, ¿solo habrá dos usuarios (como su ejemplo) o puede haber un número ilimitado de usuarios? – chezy525
Puede haber más de 2, el ejemplo fue simplificado. – jvenema