Sql 用户登录后立即发送消息的时间百分比是多少?
我以前从未问过这样的问题,也不知道这有多可能。假设我有下表:Sql 用户登录后立即发送消息的时间百分比是多少?,sql,postgresql,window-functions,Sql,Postgresql,Window Functions,我以前从未问过这样的问题,也不知道这有多可能。假设我有下表: user_id date event 22 2012-05-02 11:02:39 login 22 2012-05-02 11:02:53 send_message 22 2012-05-02 11:03:28 logout 22 2012-05-02 11:04:09 login 22 2012-05-02 11:03:16 send_message
user_id date event
22 2012-05-02 11:02:39 login
22 2012-05-02 11:02:53 send_message
22 2012-05-02 11:03:28 logout
22 2012-05-02 11:04:09 login
22 2012-05-02 11:03:16 send_message
22 2012-05-02 11:03:43 search_run
如何计算用户登录并在2分钟内发送消息的时间百分比?对于给定用户:
SELECT round(count(*) FILTER (WHERE sent_in_time) * 100.0 / count(*), 2) AS pct_sent_in_time
FROM (
SELECT (min(date) FILTER (WHERE event = 'send_message')
- min(date)) < interval '2 min' AS sent_in_time
FROM (
SELECT date, event
, count(*) FILTER (WHERE event = 'login')
OVER (ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS grp
FROM tbl
WHERE user_id = 22 -- given user
) sub1
GROUP BY grp
) sub2;
对于所有用户:
SELECT user_id
, round(count(*) FILTER (WHERE sent_in_time) * 100.0 / count(*), 2) AS pct_sent_in_time
FROM (
SELECT user_id
, (min(date) FILTER (WHERE event = 'send_message')
- min(date)) < interval '2 min' AS sent_in_time
FROM (
SELECT user_id, date, event
, count(*) FILTER (WHERE event = 'login')
OVER (PARTITION BY user_id ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS grp
FROM tbl
) sub1
GROUP BY user_id, grp
) sub2
GROUP BY user_id;
我扩展了测试用例以使其更具揭示性,因此使用了不同的百分比。见:
小提琴
在每次新登录后对数据进行分区,并检查“发送消息”是否在2分钟内发生。然后计算百分比和四舍五入
值得注意的是,这并没有被许多连续的登录所愚弄,在不到2分钟的时间里,我就用一条消息登录了
相关的:
旁白:时间戳列的名称日期很容易引起误解。在您的系统中是否可能出现欧文的小提琴中描述的场景?考虑了我能想到的几乎所有解决方案后,看起来与此非常相似。
SELECT user_id
, round(count(*) FILTER (WHERE sent_in_time) * 100.0 / count(*), 2) AS pct_sent_in_time
FROM (
SELECT user_id
, (min(date) FILTER (WHERE event = 'send_message')
- min(date)) < interval '2 min' AS sent_in_time
FROM (
SELECT user_id, date, event
, count(*) FILTER (WHERE event = 'login')
OVER (PARTITION BY user_id ORDER BY date ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS grp
FROM tbl
) sub1
GROUP BY user_id, grp
) sub2
GROUP BY user_id;
user_id | pct_sent_in_time
------: | ---------------:
22 | 33.33
23 | 100.00