订阅更新

近 30 天人均会话数

SQL 实战 123 题 · 第 67 题 简单 约 2 分钟读完

LeetCode 1142 · 比率指标、去重计数、空结果处理

本文目录
  1. 面试怎么回答
  2. 题意
  3. 表结构
  4. 思路
  5. 参考解法
  6. 易错点

面试怎么回答

在近 30 天的数据上,COUNT(DISTINCT session_id) / COUNT(DISTINCT user_id),ROUND 两位,IFNULL 处理没有数据的情况。前提是一个会话只属于一个用户,否则要先按用户计数再求平均。

先把这段讲顺;面试官追问时,再展开下面的原理和细节。

详细讲解

题意

同一张活动表,计算截至 2019-07-27 的 30 天内,每个活跃用户平均有多少个会话,保留两位小数;没有活跃用户时返回 0。

表结构

  • Activity:user_id、session_id、activity_date、activity_type;每个会话只属于一个用户

思路

人均会话数 = 不同会话数 / 不同用户数。因为每个会话只属于一个用户,可以直接在全量上用两个 COUNT(DISTINCT) 相除;没有数据时除法得到 NULL,用 IFNULL 返回 0。日期范围的注意点同上一题。

参考解法

SELECT IFNULL(ROUND(COUNT(DISTINCT session_id) / COUNT(DISTINCT user_id), 2), 0) AS average_sessions_per_user
from Activity
where activity_date > date_add('2019-07-27',INTERVAL -1 MONTH)

易错点

  • 用 COUNT(*) 会把同一会话的多条行为记录算成多个会话。
  • 先算每个用户的会话数再求平均也可以,结果一样,但要多一层子查询。
刷题进度保存在当前浏览器