1. 从一道SQL题说起:数据分析笔试到底在筛什么人
每年秋招季,后台总有人问我同一个问题:数据分析岗的笔试到底考什么?是不是把SQL刷到中等难度就稳了?我每次都回一句:你去把一套完整的笔试真题从头到尾做一遍,掐着表做,做完再回来跟我聊。
2021届那场笔试,我印象很深。不是因为题目有多偏多怪,而是因为它把"数据分析"这四个字拆得特别清楚——它不考你会不会背窗口函数的语法,它考的是你能不能用数据把一个业务问题讲明白。这个区别,决定了你是"会写SQL的人"还是"能做数据分析的人"。
这篇文章适合三类人看:第一类,正在准备数据分析岗秋招、想搞清楚笔试真实难度和考察重点的应届生;第二类,已经工作但想转行做数据分析、需要摸清入门门槛的职场人;第三类,带团队的技术负责人,想了解现在数据分析岗的筛选标准到底卡在哪一层。
我会围绕那场笔试的题型结构、每类题背后的考察意图、以及我后来复盘总结出的备考路径,把这件事讲透。不是给你一份"题库",而是给你一套"解题思维"。因为笔试题目每年都在变,但考察的底层能力,几年都没怎么动过。
先说一个反直觉的结论:数据分析笔试里,纯SQL写法的难度,往往低于大多数人的预期。真正拉开差距的,是统计推断题的严谨性、业务分析题的框架感,以及你在时间压力下的取舍能力。很多人栽跟头,不是因为不会,而是因为把时间花错了地方。
2. 那场笔试的题型骨架:四类题目,四种筛人逻辑
2.1 题型分布与时间压力的真实配比
根据后来多位参与者的复盘,那场笔试的整体结构大致是这样的:选择题(含SQL、统计、概率)占一部分,SQL编程题占一部分,业务分析简答题占一部分,最后可能还有一道偏开放的数据思维题。总时长通常在一个半小时到两小时之间,题量不算小。
这里有个关键点很多人忽略:笔试的时间分配本身就是一道隐形的考题。选择题单题分值低但数量多,SQL编程题分值中等但耗时,业务分析题分值高但需要组织语言。如果你在选择题上纠结太久,后面的大题就会写得很仓促。
我后来总结出一个比较稳的节奏:选择题控制在总时长的三分之一以内,SQL编程题留出三分之一,业务分析题留足剩下的时间。这个比例不是死的,但核心原则是——把时间优先分配给能体现你分析能力的高分题,而不是在选择题里追求满分。
2.2 选择题:SQL、统计、概率三足鼎立
选择题部分,SQL相关的题目通常考的是基础语法的理解,比如JOIN的类型区别、GROUP BY和HAVING的执行顺序、NULL值的处理逻辑。这些题不难,但容易在细节上翻车。比如很多人分不清WHERE和HAVING的区别,或者对LEFT JOIN后WHERE条件过滤的时机理解有偏差。
统计和概率题是另一个重头。常见的考点包括:假设检验的基本逻辑、置信区间的含义、常见分布的特征、条件概率和贝叶斯公式的应用。这类题的特点是,如果你只是背了公式,很容易被绕进去。比如题目给你一个场景,问"以下哪个说法是正确的",选项里往往有那种"看起来对但概念偷换"的干扰项。
我个人的经验是,选择题里最值得花时间的是统计概念题,因为它直接反映你有没有系统的统计思维。SQL语法题反而可以快速过,因为会就是会,不会就是不会,纠结也纠结不出答案。
2.3 SQL编程题:不是考语法,是考"拆解问题的顺序"
SQL编程题通常会给一个或几个表结构,然后让你写查询实现某个业务需求。比如"找出每个部门薪资最高的员工"、"计算用户次日留存率"、"统计连续登录超过三天的用户"。
这些题目的难点不在语法本身,而在于你能不能把业务需求翻译成一步步的数据操作。以"连续登录超过三天"为例,很多人第一反应是用窗口函数做日期差,但具体怎么写、怎么处理日期不连续的情况、怎么去重,这些细节才是真正拉开差距的地方。
我见过太多人,窗口函数语法背得滚瓜烂熟,但拿到题目后不知道从哪下手。原因很简单:他们缺的不是语法知识,而是把复杂问题拆成简单步骤的能力。这个能力,只能通过大量练习和复盘来培养。
2.4 业务分析题:最像"真实工作"的部分
业务分析题通常是给你一个业务场景,比如"某产品最近日活下降,请分析可能的原因并提出验证方案",或者"如果让你设计一个指标来衡量用户健康度,你会怎么设计"。
这类题没有标准答案,但有评分维度。阅卷人看的是:你有没有结构化的分析框架?你能不能区分"现象"和"原因"?你提出的验证方案是否可落地?你有没有考虑到数据口径和边界条件?
我后来跟一位参与过阅卷的朋友聊过,他说业务分析题最怕看到两种答案:一种是"我觉得可能是XX原因"然后就没有然后了;另一种是堆砌一堆专业术语但逻辑链条断裂。好的答案一定是"假设-验证-结论"的闭环,哪怕假设不完美,只要逻辑自洽、验证路径清晰,就能拿到不错的分数。
3. SQL编程题的实战拆解:从"会写"到"写对"
3.1 窗口函数类题目:连续登录问题的完整解法
连续登录问题是SQL编程题里的经典题型,也是那场笔试里被讨论最多的题目之一。题目大意是:给定一张用户登录记录表,找出连续登录超过三天的用户。
这道题的核心思路是"日期减去行号"的技巧。具体来说,如果用户连续登录,那么登录日期减去按日期排序的行号,得到的差值应该是相同的。基于这个规律,我们可以把连续登录的用户分组,然后统计每组的记录数。
-- 假设表结构为 user_login(user_id, login_date) WITH ranked AS ( SELECT user_id, login_date, DATE_SUB(login_date, INTERVAL ROW_NUMBER() OVER ( PARTITION BY user_id ORDER BY login_date ) DAY) AS grp FROM ( SELECT DISTINCT user_id, login_date FROM user_login ) t ) SELECT user_id FROM ranked GROUP BY user_id, grp HAVING COUNT(*) >= 3;这段代码有几个细节值得说。第一,我先用DISTINCT去重,因为同一天可能有多条登录记录,不去重会导致行号计算错误。第二,DATE_SUB的第二个参数是行号,这里假设行号从1开始,日期减去行号后,连续日期的差值会保持一致。第三,最后按user_id和grp分组,统计每组数量,筛选出大于等于3的。
注意:不同数据库的日期函数写法不同,MySQL用DATE_SUB,其他数据库可能需要用日期加减的语法。笔试时如果没指定数据库,建议在注释里说明你假设的数据库类型。
3.2 留存率计算:分子分母的口径陷阱
留存率是数据分析岗笔试的高频考点。题目通常会给你一张用户行为表,让你计算次日留存、七日留存等指标。
这类题最大的坑不在SQL写法,而在口径定义。比如"次日留存"的定义是:某天新增的用户中,第二天仍然活跃的比例。这里有两个关键点:第一,"新增用户"怎么定义?是首次注册还是首次活跃?第二,"第二天仍然活跃"是指第二天有任意行为,还是有特定行为?
-- 计算次日留存率 WITH first_day AS ( -- 每个用户的首次活跃日期 SELECT user_id, MIN(login_date) AS first_date FROM user_login GROUP BY user_id ), next_day_active AS ( -- 首次活跃后第二天仍然活跃的用户 SELECT f.user_id, f.first_date FROM first_day f JOIN user_login l ON f.user_id = l.user_id AND l.login_date = DATE_ADD(f.first_date, INTERVAL 1 DAY) ) SELECT f.first_date, COUNT(DISTINCT f.user_id) AS new_users, COUNT(DISTINCT n.user_id) AS retained_users, ROUND(COUNT(DISTINCT n.user_id) / COUNT(DISTINCT f.user_id), 4) AS retention_rate FROM first_day f LEFT JOIN next_day_active n ON f.user_id = n.user_id GROUP BY f.first_date;这道题的关键在于,你要在答案里明确写出你的口径假设。比如我会加一句注释:"此处定义新增用户为首次登录用户,次日活跃定义为次日有登录记录。"这样即使阅卷人的口径和你不同,也能看到你的逻辑是清晰的。
3.3 排名与TopN问题:ROW_NUMBER和RANK的选择
"找出每个部门薪资最高的员工"这类题目,核心是排名函数的选择。ROW_NUMBER、RANK、DENSE_RANK三个函数都能排名,但行为不同。
- ROW_NUMBER:相同值也按顺序编号,结果唯一。
- RANK:相同值编号相同,后续编号跳跃。
- DENSE_RANK:相同值编号相同,后续编号不跳跃。
如果题目说"薪资最高的员工",且可能存在并列最高的情况,用RANK或DENSE_RANK更合适。如果只需要一个代表,用ROW_NUMBER。
-- 找出每个部门薪资最高的员工(允许并列) WITH ranked AS ( SELECT dept_id, emp_id, salary, RANK() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS rk FROM employee ) SELECT dept_id, emp_id, salary FROM ranked WHERE rk = 1;我个人的习惯是,在笔试答案里把选择理由写清楚。比如加一句注释:"使用RANK以保留并列最高薪资的情况。"这比单纯写代码更能体现你的思考深度。
4. 统计与概率题:那些"看起来会做但一做就错"的坑
4.1 假设检验:p值到底在说什么
假设检验是统计题里的重灾区。很多人能背出"p值小于0.05就拒绝原假设",但被问到"p值的准确定义是什么"时就卡壳了。
p值的定义是:在原假设为真的条件下,观察到当前样本结果或更极端结果的概率。注意,它不是"原假设为真的概率",也不是"结论错误的概率"。这两个误解在选择题里经常作为干扰项出现。
还有一个常见坑是单尾和双尾检验的选择。题目如果问"某药物是否有效",通常用双尾检验,因为你要检验的是"有效"还是"无效",两个方向都关心。如果问"某药物是否比对照组更好",则用单尾。这个判断逻辑在笔试里经常考。
4.2 置信区间:频率学派的解释
置信区间的解释也是高频考点。95%置信区间的正确解释是:如果重复抽样无数次,每次构造一个置信区间,那么大约95%的区间会包含真实参数值。它不是"真实参数有95%的概率落在这个区间内"。
这个区别在选择题里经常被拿来设陷阱。我见过一道题,选项A说"真实均值有95%的概率在区间内",选项B说"重复抽样下95%的区间会包含真实均值"。正确答案是B,但很多人会选A,因为直觉上A更"顺口"。
4.3 条件概率与贝叶斯:别被"基础率"骗了
贝叶斯公式的应用题,经典场景是疾病检测。比如"某疾病患病率1%,检测灵敏度99%,特异度95%,某人检测阳性,他实际患病的概率是多少?"
很多人第一反应是"99%",但正确答案远低于这个数。原因是基础率效应:患病率太低,即使检测很准,阳性结果里也有大量假阳性。
# 贝叶斯计算示例 p_disease = 0.01 # 患病率 p_pos_given_disease = 0.99 # 灵敏度 p_pos_given_healthy = 0.05 # 1 - 特异度 p_pos = p_pos_given_disease * p_disease + p_pos_given_healthy * (1 - p_disease) p_disease_given_pos = p_pos_given_disease * p_disease / p_pos print(f"检测阳性后实际患病概率: {p_disease_given_pos:.4f}") # 输出约为 0.1667,即约16.67%这道题的关键是画清楚条件概率的树状图,把"患病且阳性"、"健康且阳性"两条路径分开算。笔试时如果时间紧,至少要把公式写出来,因为过程分往往比结果分更重要。
5. 业务分析题的答题框架:让阅卷人一眼看到你的逻辑
5.1 指标下降类问题:先拆维度,再提假设
"某产品日活下降,请分析原因"是业务分析题的经典题型。很多人上来就写"可能是用户流失了",这种答案基本拿不到分,因为它没有提供任何可验证的信息。
我的答题框架是这样的:先确认数据口径,再拆解维度,然后提出假设,最后给出验证方案。
第一步,确认口径。日活下降是绝对值下降还是相对值下降?统计口径有没有变化?数据采集有没有异常?这一步很多人跳过,但它是排除"假问题"的关键。
第二步,拆维度。把日活按时间、渠道、用户分层、地区、设备等维度拆开,看下降是全局性的还是局部性的。如果是局部性的,问题范围就缩小了。
第三步,提假设。基于拆解结果,提出可能的解释。比如"新用户次日留存下降导致日活下降"、"某渠道投放减少导致新增下降"、"竞品活动导致老用户流失"。
第四步,验证方案。针对每个假设,设计验证方法。比如"对比下降前后新用户留存曲线"、"检查渠道投放数据"、"分析竞品活动时间线"。
5.2 指标设计类问题:从"北极星"到"护栏"
"设计一个衡量用户健康度的指标"这类题,考察的是你的指标体系思维。我的建议是先定北极星指标,再配护栏指标。
北极星指标是能反映产品核心价值的单一指标。比如内容社区可能用"日均互动用户数",电商可能用"月均购买用户数"。护栏指标是防止北极星指标被"刷"坏的约束条件,比如"用户投诉率"、"退款率"。
答题时我会先说明选择北极星指标的理由,然后列出2-3个护栏指标,最后说明这些指标如何组合使用。这样既体现了系统性,又展示了落地意识。
5.3 AB实验类问题:别忽略"统计功效"
AB实验题在数据分析笔试里越来越常见。题目可能问"实验组和对照组差异显著,是否可以直接上线",或者"实验没有显著差异,可能的原因是什么"。
这类题的核心考点是统计功效和实际显著性。统计显著不代表业务上有意义,样本量太小也可能导致检验不出真实差异。答题时要提到样本量估算、实验周期、多重比较校正等概念。
我见过一道题,实验组转化率提升0.1%,p值小于0.05,问是否上线。正确答案是"需要结合业务成本判断,统计显著不等于业务显著"。这种题考的就是你有没有"数据为业务服务"的意识。
6. 备考路径复盘:从"刷题"到"建体系"
6.1 基础阶段:SQL和统计的"最小必要知识"
备考初期,我建议把精力集中在两件事上:SQL的核心语法和统计的基本概念。
SQL方面,重点掌握:JOIN的几种类型及区别、GROUP BY和HAVING、窗口函数(ROW_NUMBER、RANK、SUM OVER等)、子查询和CTE。不需要追求偏门语法,把这几类练熟,笔试里的SQL题基本都能应付。
统计方面,重点理解:描述统计(均值、中位数、方差)、概率分布(正态、二项、泊松)、假设检验(t检验、卡方检验)、置信区间、贝叶斯公式。不需要推导公式,但要能解释每个概念的含义和适用场景。
6.2 强化阶段:按题型专项突破
基础打牢后,进入专项突破阶段。我的做法是按题型分类刷题,而不是随机刷。
比如这一周专攻窗口函数类题目,把连续登录、TopN、同比环比、留存率这几类题各做5-10道,做完后总结每类题的通用解法和易错点。下一周专攻业务分析题,找10个不同的业务场景,每个场景写一份完整的分析框架,然后对照优秀答案找差距。
这个阶段的关键是建立"题型-解法"的映射。笔试时时间紧,你没有太多时间现场推导,更多是靠模式识别快速定位解法。
6.3 冲刺阶段:限时模拟和错题复盘
考前两周,进入限时模拟阶段。找完整的真题或模拟题,掐着时间做,模拟真实笔试的压力环境。
做完后一定要复盘。复盘的重点不是"这道题我为什么错了",而是"我在哪个环节浪费了时间"、"我的答题顺序是否合理"、"哪些知识点我反复出错"。把这些记录下来,考前最后一天只看这些复盘笔记。
我个人的经验是,错题复盘的价值远大于刷新题。因为笔试的题型是有限的,你把错题吃透,比盲目刷一百道新题更有效。
7. 那些没人告诉你但很重要的细节
7.1 答题顺序:先做"确定性高"的题
笔试时,我建议先快速浏览一遍所有题目,然后按"确定性从高到低"的顺序做。先做你一眼就知道怎么做的题,把能拿的分先拿到手,再回头啃难题。
这个策略的好处是,即使后面难题没做完,你的基础分也是稳的。很多人习惯按题目顺序做,结果卡在一道难题上,后面会做的题反而没时间写。
7.2 代码注释:让阅卷人看到你的思路
SQL编程题里,我强烈建议写注释。哪怕代码写得不够优雅,只要注释清楚说明了你的思路和口径假设,阅卷人就能理解你的逻辑,给分也会更宽容。
比如在留存率题里加一句"-- 定义新增用户为首次登录用户",在排名题里加一句"-- 使用RANK保留并列情况"。这些注释花不了几秒钟,但能显著提升你的答案质量。
7.3 业务分析题:先写框架,再填内容
业务分析题最怕"想到哪写到哪"。我的习惯是先用30秒列一个提纲,把要写的几个部分标出来,然后再逐部分展开。
提纲不需要很详细,比如"口径确认-维度拆解-假设提出-验证方案"四个关键词就够了。有了提纲,你的答案就有了骨架,阅卷人一眼就能看到你的逻辑结构。
7.4 时间不够时:优先保证"过程分"
如果时间实在不够,最后一道大题只能写个开头,那就把框架写出来。比如业务分析题,哪怕你只写了"我会从用户、渠道、产品三个维度拆解,具体验证方案包括...",也比空白强。因为阅卷人能看到你的分析思路,过程分往往比结果分占比更高。
8. 从笔试到面试:数据分析能力的连续考察
笔试只是第一关,后面的面试才是真正的硬仗。但好消息是,笔试和面试考察的核心能力是一致的:SQL的熟练度、统计的严谨性、业务分析的框架感。
我后来复盘自己的经历,发现笔试里踩过的坑,面试里几乎都会再遇到一遍。比如笔试里没写清楚口径假设,面试时被问到"你这个指标怎么定义的"就会卡壳。笔试里业务分析题逻辑不清晰,面试时案例分析也会露怯。
所以我的建议是,把笔试当成一次"压力测试",不是为了通过而通过,而是通过它发现自己的薄弱环节,然后在面试前有针对性地补强。
那场笔试过去好几年了,但每次有人问我数据分析岗怎么准备,我还是会拿它当例子。因为它把数据分析的核心能力拆得很清楚:SQL是工具,统计是底层逻辑,业务分析是落地能力。三者缺一不可,但优先级在不同阶段不同。如果你现在还在准备阶段,我的建议是先把SQL和统计的基础打牢,再花时间练业务分析。因为前两者有标准答案,后者需要积累和悟性。而笔试的时间压力,恰恰会放大你基础不牢的地方。