SQL 面试题:每日活跃用户的 1日、3日、7日留存率怎么算?
SQL 面试题每日活跃用户的 1日、3日、7日留存率怎么算前段时间面试 的时候遇到一道留存率 SQL 题。题目本身不算特别难但我当时一看到“留存率”第一反应就是MIN(active_date)OVER(PARTITIONBYuser_id)然后那叫一个体直口快开始一顿窗口函数操作自我感觉还挺优雅。结果炫技炫错了 面试官要算的是每日活跃用户留存而我写出来的其实更接近新增用户留存两个都叫留存但最大的区别只有一个分母不是同一批人。这道题也算给大家提了个醒SQL 面试有时候不是函数不会而是业务口径先理解错了。一、题目有一张用户活跃表active_user active_date BIGINT -- 活跃日期例如 20260101 user_id BIGINT -- 用户 ID要求统计2026-01-01 2026-01-08 每天的活跃用户数以及对应的 1 日、3 日、7 日留存率。留存率定义某天活跃且 N 天后仍然活跃的用户数 / 当天活跃用户数最终结果类似日期 活跃用户数 1日留存率 3日留存率 7日留存率 20260108 X1 20260107 X2 Y1% 20260106 X3 Y2% 20260105 X4 Y3% Z1% 20260104 X5 Y4% Z2% ... 20260101 X8 Y7% Z4% W1%比如 01-08 没有次日留存因为题目的观察窗口只到 01-08。同理越靠后的日期3 日、7 日留存也可能暂时无法计算。二、我当时为什么会写错我当时直接想到了MIN(active_date)OVER(PARTITIONBYuser_id)这个 SQL 本身当然没问题。问题是MIN(active_date)找的是这个用户第一次活跃的日期。比如用户 A 的活跃记录是20260101 20260105 20260106那么MIN(active_date)得到的永远是20260101但当我们统计20260105的日活留存时用户 A 明明应该属于01-05 当天的活跃用户应该被算进 01-05 的分母。如果按照首次活跃日期去分组A 会一直被归到 01-01 那批用户里。这样 01-05 的分母就错了。所以MIN(active_date)OVER(...)更适合计算新增用户 / 首次活跃用户的留存而不是这道题要求的每日全量活跃用户留存三、正确思路其实很简单假设 01-01 有 4 个活跃用户A B C D01-02 还有A C那么1日留存率 2 / 4 50%如果到了 01-04只剩 A 还活跃3日留存率 1 / 4 25%所以这道题根本不用先找什么“首次活跃日期”。只需要拿当天活跃的用户去找 1 天、3 天、7 天后这个用户还在不在。这也是后来我按照面试官提示写出来的思路。四、LEFT JOIN 解法面试现场其实直接写 3 次LEFT JOIN就够了非常直观SELECTa.active_dateAS日期,-- 当天活跃用户数也就是分母COUNT(DISTINCTa.user_id)AS活跃用户数,-- 1 日留存COUNT(DISTINCTb1.user_id)*1.0/COUNT(DISTINCTa.user_id)AS1日留存率,-- 3 日留存COUNT(DISTINCTb3.user_id)*1.0/COUNT(DISTINCTa.user_id)AS3日留存率,-- 7 日留存COUNT(DISTINCTb7.user_id)*1.0/COUNT(DISTINCTa.user_id)AS7日留存率FROM(SELECTactive_date,user_idFROMactive_userWHEREactive_dateBETWEEN20260101AND20260108)aLEFTJOINactive_user b1ONa.user_idb1.user_idANDDATEDIFF(b1.active_date,a.active_date)1LEFTJOINactive_user b3ONa.user_idb3.user_idANDDATEDIFF(b3.active_date,a.active_date)3LEFTJOINactive_user b7ONa.user_idb7.user_idANDDATEDIFF(b7.active_date,a.active_date)7GROUPBYa.active_dateORDERBYa.active_date;核心其实就看两个地方。分母COUNT(DISTINCTa.user_id)代表当天所有活跃用户。分子COUNT(DISTINCTb1.user_id)代表当天活跃并且 1 天后又活跃的用户。3 日和 7 日完全一样。面试写到这里核心逻辑基本已经答出来了。注题目里的active_date是 BIGINT。实际在 Hive / Spark SQL 中需要根据具体引擎先转换成 DATE 再使用DATEDIFF。面试时如果默认日期字段可直接参与日期计算可以先重点写业务逻辑。另外如果严格按照题目“观察窗口截止 01-08”像 01-08 的次日留存应该展示为NULL而不是 0。这个可以再通过CASE WHEN补充处理属于边界展示问题不影响核心思路。五、这道题真正的坑分母是谁复盘下来这道题最重要的其实不是LEFT JOIN而是看到“留存率”三个字先确认分母到底是谁。1. 日活留存比如统计 01-05 的次日留存。分母是01-05 当天所有活跃用户不管这个用户是当天刚来的还是已经用了三年的老用户只要 01-05 活跃都算进去。分子是01-05 活跃并且 01-06 仍然活跃的用户所以日活留存更偏向衡量产品整体的用户粘性。SQL 思路也很直接a.user_idb.user_idANDDATEDIFF(b.active_date,a.active_date)N2. 新增用户留存如果题目换成统计每天新增用户的次日留存率。这时候分母就不是当天所有活跃用户了而是当天第一次出现的用户比如一个用户01-01 活跃 01-05 活跃 01-06 活跃他属于 01-01 的新增用户不属于 01-05 的新增用户。这时候我面试时想到的MIN(active_date)OVER(PARTITIONBYuser_id)反而就对了。六、如果题目真的问新增留存MIN 开窗就很好用假设题目变成求 2026-10-01 2026-10-07 期间新增用户的次日留存率。这时候可以先给每个用户找到首次活跃日期WITHfirst_loginAS(SELECTuser_id,active_date,MIN(active_date)OVER(PARTITIONBYuser_id)ASfirst_active_dateFROMactive_user)SELECTfirst_active_dateAS新增日期,COUNT(DISTINCTuser_id)AS新增用户数,COUNT(DISTINCTIF(DATEDIFF(active_date,first_active_date)1,user_id,NULL))AS次日留存人数,ROUND(COUNT(DISTINCTIF(DATEDIFF(active_date,first_active_date)1,user_id,NULL))*1.0/COUNT(DISTINCTuser_id),4)AS次日留存率FROMfirst_loginWHEREfirst_active_dateBETWEEN2026-10-01AND2026-10-07GROUPBYfirst_active_date;这时候MIN(active_date)OVER(PARTITIONBYuser_id)就是在给每个用户打一个标签你第一次出现是哪一天然后再用DATEDIFF(active_date,first_active_date)判断这个用户第一次出现后的第 1 天、第 3 天、第 7 天有没有再次活跃。所以MIN() OVER()并不是写错了。只是我把它用错题了 另外严格来说MIN(active_date)得到的是“首次活跃日期”。只有当数据覆盖了用户完整生命周期或者业务上约定首次活跃就等价于新增时才能把它直接当作“新增日期”。七、最后复盘这道题现在回头看其实挺简单。日活留存今天所有来过的人N 天后还有多少人回来用当天活跃用户去LEFT JOINN 天后的活跃记录。新增留存今天第一次来的人N 天后还有多少人回来先用MIN(active_date)OVER(PARTITIONBYuser_id)找到首次活跃日期再计算后续留存。所以以后再碰到留存题我估计不会再第一时间想窗口函数了而是会先思考这个留存率的分母是谁这次属于典型的窗口函数秀起来了答案也一起秀没了 不过面试里写错一次确实比自己刷十道类似的题记得牢。

相关新闻

对比磁场电磁铁供应商选哪家意外揭秘

对比磁场电磁铁供应商选哪家意外揭秘

引言在众多工业和科研领域,取向成型电磁铁磁场的应用至关重要。它能够为材料的取向成型提供必要的磁场环境,从而改善材料的性能。然而,面对市场上众多的磁场电磁铁供应商,如何选择一家靠谱的供应商成为了许多用户的难题。本文将深…

2026/8/26 16:28:26 阅读更多 →
如何在服务器使用ClaudeCode

如何在服务器使用ClaudeCode

什么是ClaudeCode ClaudeCode是使用Anthropic的Claude API作为能力底座&#xff0c;专注于AI编程的工具。Claude模型能力划分&#xff1a;Haiku俳句<Sonnet十四行诗<Opus作品&#xff0c;能力越强&#xff0c;Token消耗越多。 安装 安装node环境由于ClaudeCode这个客户端…

2026/8/26 16:27:26 阅读更多 →
大型量产固件的工程实践(九):GPIO 模拟 SPI 驱动设计

大型量产固件的工程实践(九):GPIO 模拟 SPI 驱动设计

大型量产固件的工程实践&#xff08;九&#xff09;&#xff1a;GPIO 模拟 SPI 驱动设计本文是《大型量产固件的工程实践》专栏第 9 篇。 上一篇&#xff1a;第 8 篇《多款同类型芯片驱动的统一抽象》 &#xff5c; 下一篇&#xff1a;第 9 篇实战《GPIO 模拟 SPI 实现源码与使…

2026/8/26 16:27:26 阅读更多 →

最新新闻

ms-swift零基础学习教材

ms-swift零基础学习教材

ms-swift 零基础学习教材&#xff1a;从推理到 LoRA 微调与部署 适合刚开始学习 AI 和编程的。你不需要一次看懂全部内容&#xff0c;也不需要死记参数。 第一次只完成“第 0 关 → 第 1 关 → 第 2 关”&#xff1b;成功后再学习自定义数据和参数调节。 本文依据 2026 年 8 月…

2026/8/26 17:11:37 阅读更多 →
OpenCV面试题

OpenCV面试题

opencv面试复习 1 OpenCV 中 cv::Mat 的深拷贝和浅拷贝问题cv::Mat 默认赋值和拷贝构造是浅拷贝&#xff0c;只复制矩阵头信息&#xff0c;底层像素数据共享&#xff0c;OpenCV 通过引用计数管理内存。这样可以减少大图像复制带来的性能开销。如果需要真正复制图像数据&#xf…

2026/8/26 17:11:37 阅读更多 →
Git 重置模式详解:四种重置方式的原理与应用场景

Git 重置模式详解:四种重置方式的原理与应用场景

引言 在日常使用 Git 进行版本控制的过程中&#xff0c;开发者时常需要调整提交历史或清理工作区状态。git reset 命令是最常用的历史重写工具之一&#xff0c;但其四种重置模式——软重置&#xff08;soft&#xff09;、混合重置&#xff08;mixed&#xff09;、硬重置&#x…

2026/8/26 17:11:37 阅读更多 →
scrapy爬取动态页面的正确姿势

scrapy爬取动态页面的正确姿势

不能否认, 它是相当出色的爬虫框架, 其借用的是相似的办法去爬取网页, 即所爬取的是静态页面, 然而实际情形是, 多数网站均为动态的, 我们所见到的正常页面皆是经浏览器渲染后的成果, 倘若径直运用爬取网页的方式, 极有可能无法获取到预期的数据。一种看似理所当然的办法, 便是…

2026/8/26 17:11:37 阅读更多 →
Level 4自动驾驶系统设计45——L2/L3 级软硬件架构 1

Level 4自动驾驶系统设计45——L2/L3 级软硬件架构 1

8.2 L3 级方案:单片 32G/64G 算力 SoC 运行端到端感知网络的性能瓶颈 8.2.1 责任边界重划对 L3 级单片方案的“物理拷问” 从 Level 2 级的“失效安全(Fault-Safe,见 8.1 节)”跨越到 Level 3 级有条件自动驾驶,汽车工业的核心变阵不仅是算法性能的提升,更是法律责任主…

2026/8/26 17:11:37 阅读更多 →
手把手教你学Simulink——构网型控制(Grid‑Forming / GFM)逆变器稳定性分析仿真

手把手教你学Simulink——构网型控制(Grid‑Forming / GFM)逆变器稳定性分析仿真

目录 手把手教你学Simulink——构网型控制(Grid‑Forming / GFM)逆变器稳定性分析仿真 一、VSG / GFM 控制原理(简化) 1.1 有功‑频率 Droop + 虚拟惯量 1.2 无功‑电压 Droop 1.3 电压‑电流双内环(同步旋转 dq) 二、关键参数 三、Simulink 建模(手把手) 3.1 S…

2026/8/26 17:10:35 阅读更多 →

日新闻

Python random 模块常用函数详解:从入门到实战

Python random 模块常用函数详解:从入门到实战

目录 1. 引言2. 准备工作3. 基础随机函数4. 序列相关函数5. 随机种子与复现6. 实战案例7. 注意事项8. 常见问题与排查9. 总结 1. 引言 摘要&#xff1a; 本文系统介绍 Python 标准库 random 模块中最常用的随机数生成函数。内容涵盖基础随机函数&#xff08;random()、unifor…

2026/8/26 0:00:40 阅读更多 →
《Microsoft Sql server 2008 Internals》读书笔记--第三章Databases and Database Files(2)

《Microsoft Sql server 2008 Internals》读书笔记--第三章Databases and Database Files(2)

《Microsoft Sql server 2008 Internals》索引目录&#xff1a; 《Microsoft Sql server 2008 Internals》读书笔记--目录索引 在上篇文章中&#xff0c;主要介绍了创建数据库的基本语法和FileGroup的初步知识。需要注意的是: 关于FileGroup 如果你的系统是用Raid设备直接存…

2026/8/26 1:18:18 阅读更多 →
政务AI智能体怎么建?三种模式、三步路径与四个误区

政务AI智能体怎么建?三种模式、三步路径与四个误区

政务AI智能体已经从概念试点阶段&#xff0c;转入了政务服务的常态化落地应用&#xff1b;在实际使用过程中&#xff0c;它能自主理解办事需求、辅助完成填报申报、开展材料预审&#xff0c;并联动多个系统协同作业&#xff0c;真正嵌入到政务办理的全流程当中。但在落地推进过…

2026/8/26 1:18:18 阅读更多 →

周新闻

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

首先光是一种能量的载体和形态&#xff0c;宏观上观察到的光是由无数个微观的光量子组成的&#xff0c;每个光子在产生的瞬间&#xff0c;其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前&#xff0c;在微观层面&#xff0c;每个光量子的运动轨迹是以波函数所展现…

2026/8/26 14:45:33 阅读更多 →
SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

1. 通话转接不是“挂断再拨号”&#xff0c;而是SIP会话的动态重定向你有没有遇到过这样的场景&#xff1a;客服坐席A正在和客户通电话&#xff0c;突然需要把这通对话无缝转给专家坐席B&#xff0c;客户完全感知不到中间的断连——既没听到忙音&#xff0c;也没被要求重新拨号…

2026/8/25 3:38:18 阅读更多 →
Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

1. 为什么选择Kolla-ansible来部署单节点OpenStack&#xff1f;如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法&#xff0c;那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

2026/8/26 14:46:37 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速&#xff1a;macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/26 3:50:20 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南&#xff1a;3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗&#xff1f;ncmdump解密工具帮你轻松解决这个困…

2026/8/25 10:31:12 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片&#xff1a;为英语学习 App 打造桌面级学习助手适用平台&#xff1a;HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0&#xff08;API 26 Beta&#xff09;新增了 AgentCard 智能体卡片能力&#xff0c;这是继 HMAF&#xff08;鸿蒙智能体框架&#x…

2026/8/26 1:24:05 阅读更多 →