数据分析师SQL能力地图:五层模型与避坑清单

发布时间:2026/10/5 3:29:35
数据分析师SQL能力地图:五层模型与避坑清单 SQL 这个题目几乎每个想转行数据分析的人都会问一嘴也是我带过的新人里最容易“不知道往哪个方向使劲”的问题。我见过有人抱着《SQL 必知必会》啃了三遍上来写个多表关联还是卡壳也见过非科班出身的朋友SQL 水平完全够用反而在业务沟通上栽了跟头。说到底数据分析师的 SQL 和开发工程师的 SQL、DBA 的 SQL根本不是一个物种不能用同一套标准去衡量。这篇文章我就直接给一个明确答案数据分析师学 SQL学到“能用它准确、高效地解决业务取数和分析需求同时能让人看懂、能维护”这个程度就够了不追求炫技更不需要钻进数据库内核里去。这个定位意味着什么意味着你的关注点不是索引怎么建最快隔离级别怎么调而是怎么把一个模糊的业务问题翻译成一段靠谱的查询怎么在几百行数据里快速发现异常怎么让同事接手你的 SQL 时候不骂人。下文我会从“能力分层”的角度把这件事拆开讲每一层对应什么场景、掌握到什么标准、哪些坑我见过别人踩过一次说清楚。如果你是刚入门的新手或者做了两年还在用 SELECT * 到处碰壁的“熟手”这篇应该能帮你建立一张明确的能力地图。1. 先搞清楚数据分析师要的 SQL 和开发要的 SQL差在哪很多自学 SQL 的人最容易犯的错是拿开发者的标准来要求自己结果把大量时间耗在性能调优、存储过程、事务控制这些数据仓库场景里基本用不上的东西上。实际上数据分析师日常面对的数据库绝大多数是别人已经搭好的数据仓库或数据中台你的角色是“高效使用”它而不是“建设维护”它。1.1 核心需求解析你不是在“写程序”你是在“问问题”数据分析师写 SQL 的本质是把自己脑子里的业务问题翻译成数据库能理解的语言然后把数据拿回来继续加工。这个定位决定了几个关键能力。第一准确理解业务指标的能力。比如运营说“想看下最近 30 天的用户留存”你能不能立刻意识到这里需要定义“新用户”“活跃用户”“留存”三个口径而不是闷头就开始 SELECT。第二熟练运用常用语法和函数的能力。JOIN、GROUP BY、WHERE、CASE WHEN、窗口函数这些是日常最高频的工具要熟到肌肉记忆的程度而不是每次都要翻手册。第三发现和处理数据异常的能力。结果里出现 NULL 堆积、重复值爆炸、时间字段格式混乱你能不能快速定位原因并解决这决定你交付的表格是否可靠。这三件事没有一个要求你理解数据库的底层存储结构更不要求你懂索引优化但每件事都对“熟练度”有要求。所谓熟练就是看到一个需求脑子里能迅速浮现出完整的查询框架而不是边写边想。1.2 为什么很多人学了两年 SQL 还是写不好我带过的学员里不少人是“语法全会题目全废”的状态。让他们单独解释 LEFT JOIN 和 INNER JOIN 的区别人人都能说但一到真需求“找出最近一个月有下单但没付款的用户”就开始乱了。这个现象背后通常有三个原因。第一个原因练习和实战脱节。教程里的数据都是干净的字段名规范、无重复、无缺失但真实数据永远是一片狼藉日期格式不统一、地区字段有空值、同一个人有多条一模一样的记录。如果只在干净数据上做练习遇到脏数据就会手足无措。第二个原因缺少从业务语言到 SQL 语言的翻译训练。很多人习惯了“题目怎么说我就怎么写”而没有锻炼出“把一句含糊话拆解成多个明确条件”的能力。第三个原因没有建立写 SQL 的思维框架。面对一个复杂需求高手会先想清楚最终表结构长什么样需要哪些字段、什么粒度、什么时间范围再倒推怎么写新手则是一句一句往下凑写到哪算哪最后结果对不对自己都没底。看清这三个原因你就明白该往哪个方向使劲了不要沉迷于刷语法题要多做那种“给你一个业务背景让你自己定义口径并提取数据”的练习。2. 我给数据分析师划的五层 SQL 能力模型把要求量化之后学习会更有方向感。我平时带人用的是五层能力模型每一层都有明确的考核标准。你对照着看看自己卡在哪层比盲目刷题有用得多。2.1 第一层能取数且能保证取出来的数是对的这一层是底线也是最容易翻车的地方。所谓取数不单是把数据“取出来”而是取出来的结果必须业务上可信。很多人第一次独立取数跑出来和业务方给的数字差了好几万排查了半天发现是 JOIN 的时候没注意字段重复一对多把行数放大了。这一层的考核标准有四个第一能用 JOIN 连接多张表并说清楚 INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL OUTER JOIN 在自己业务场景里的实际差异第二能用 WHERE 做精准过滤能区分 WHERE 在 JOIN 前过滤和 JOIN 后过滤的结果差异第三能用 GROUP BY 做分组汇总并理解聚合函数和 HAVING 的配合第四能通过对比 COUNT(*) 和 COUNT(DISTINCT 字段) 来验证数据有没有重复。达到这个标准你就能应付大部分日常取数需求了。但难点不在这里而在于如何验证结果是对的。我的习惯是交叉验证多写一个不同逻辑的查询用不同的方式算同一个指标对不上就说明有问题。2.2 第二层会用窗口函数解决“排名、累计、同环比”这类分析问题窗口函数是数据分析师 SQL 水平和取数工的分水岭。原因很简单业务分析里大量问题都涉及“按照某个维度排序后再计算”的场景比如用户付费排行、各品类销售累计占比、月度环比变化这些用普通 GROUP BY 写会非常别扭窗口函数一出手就清爽很多。我要求团队里的人至少能熟练用以下几类窗口函数。排名类ROW_NUMBER、RANK、DENSE_RANK要清楚三者的区别特别是在并列排名时的处理方式聚合窗口函数SUM、AVG、COUNT 结合 OVER(PARTITION BY ... ORDER BY ...)用来做累计值比如算截至每天的累计销售额位移类LAG、LEAD用来算环比、同比把上一期的值挪本行来做对比分位数类NTILE用于把数据均匀分桶比如按金额分层看用户分布。这一层的判断标准很简单给你一张销售流水表你能不能独立写出“每个用户最近一笔订单时间”“每个品类销量前 3 名的商品”“每个月的销售额相比上月变化率”三类查询。能的话说明这一层过关了。2.3 第三层能把复杂业务问题拆解成一段结构清晰的 SQL而不是靠嵌套堆出来取数多了你会发现真实业务问题的复杂程度远超过教程里的练习题。比如“找出连续 3 个月都有购买行为的流失召回用户”或者“计算每个销售区域中客单价高于该区域平均值的订单占比”。这类场景不是靠一两个关键字能搞定的需要你“组装”能力。这一层的关键是养成“子查询/CTE 思维”。我强烈建议不要写连环嵌套的子查询那玩意维护起来简直是灾难。要用 WITH 语句把大问题拆成一个个有业务含义的临时表先做第一层筛选和清洗再做第二步关联汇总最后得出目标结果。每个步骤都起个有意义的名字就像写文章分段一样。这样写出来的 SQL不仅不容易出逻辑错别人接手时也看得懂不用逐行猜你在想什么。这里的实操判断标准是给你一张订单表、一张用户表、一张商品表用五分钟理出“每个用户最近一次购买的商品的品类是什么”你能不能做到不假思索地拆出三步先求每个用户最近的订单时间再关联订单明细最后关联商品表。2.4 第四层有数据质量意识能发现和处理“脏数据”很多初学者的 SQL 学习完全绕开了数据清洗但实际上线以后数据脏才是常态。字段里面塞了空格、大小写不统一、日期格式五花八门、明显超出合理范围的数值、同一业务实体存在重复记录……任何一个都会让结果直接失真。这一层的核心技术点其实不复杂无非就是 NULL 处理、去重、字符串清洗、类型转换、异常值过滤这几类操作。但难的是你有没有这个意识。我的要求是写每个查询之前先默认数据是“脏”的先做一遍侦查SELECT 出来看看有没有重复、有没有空、有没有明显不合理的数据再动手写主体逻辑。这个习惯本身比掌握多少函数重要得多。具体来说你至少要做到能识别 DISTINCT 在什么场景下会掩盖问题比如你 DISTINCT 了整行却掩盖了其中某列本身的重复能用 GROUP BY HAVING 排查重复记录能处理字符串里的前导和尾随空格能把 YYYYMMDD 和 YYYY-MM-DD 两种日期格式统一。这些操作都很基础但组合起来就是一个可靠的数据分析师和毛手毛脚新人的分水岭。2.5 第五层会写“能看懂、能复用、能交接”的生产级 SQL这一层是很多人忽略的软实力却直接影响职业口碑。实际工作中你的 SQL 经常会被同事 review会被后续的人维护甚至三个月后你自己回头改需求。如果当时写得像天书受罪的还是自己。生产级 SQL 的几个习惯我现在都在团队里强制执行字段名一律显式写出不用 SELECT *所有临时结果用中文注释标注业务含义子查询用 CTE 拆开并命名不让嵌套超过三层关键步骤写注释说明“为什么这样做”而不是写“做了什么”统一大小写风格关键词全大写或全小写不要混来混去。你别小看这些习惯给团队省下的沟通成本是巨大的。一个能十分钟看懂别人 SQL 的人和需要两小时还得靠人讲解的人协作效率差出一个量级。如果说前四层决定了你“能不能做”这一层决定的是你“能不能被别人信任着一起做”。3. 明确界限哪些 SQL 内容数据分析师可以理直气壮地说“不用学”我的答案里也包括“不用学什么”。现在网上的信息太杂今天的搜索引擎一打开SQL 关键词里能蹦出 SQL 注入、SQL Server 安装报错、数据库密码过期、内网渗透之类的热门词很多人一焦虑就什么都要看其实大部分内容和你无关。守住边界把精力花在刀刃上。3.1 与业务分析无关的数据库管理与运维操作交给专门的同学数据分析师不负责装数据库也不负责数据库跑不动了怎么排查。像 SQL Server 安装失败、服务无法连接、监听程序分发错误这类问题是你偶尔会碰见、但应该直接提工单给 DBA 的事。我看到很多新手在这个上面浪费了大量时间傻乎乎地去研究 SQL Server 2019 安装步骤、去研究服务怎么启动其实对业务分析能力一点提升都没有。什么值得花时间呢把你正在用的查询工具搞明白比如你很可能会用 Navicat 或 DataGrip 连数据库知道怎么建立连接、怎么看执行结果、怎么导出数据、怎么管理 SQL 片段就够了。偶尔会因为权限问题看到“无法连接”“密码过期”之类的报错知道找到对应负责人能解决就行。我想特别提醒一点不要把宝贵的学习时间浪费在“攻防类”的内容上。比如搜索“SQL 注入”“万能密码绕过”这类词对你的数据分析工作毫无价值奥妙在于这些词汇是被搜索引擎推给所有人的并不是你需要的路标。看到这类内容直接跳过就好这和你的目标领域没有任何关系。3.2 追求极致的查询性能优化是开发工程师的活不是分析师的慢查询优化、索引优化、执行计划分析这些话题在开发场景里很重要但数据分析师不要一头扎进去。你日常写的取数 SQL数据量级在几十万到几千万行之间只要不是顶着全表扫几亿行的压力来写把前面说得多层基本功做好查询速度通常都不会是瓶颈。我见过有新人花了两周研究怎么给大表建索引、怎么改写 JOIN 顺序来提速但实际业务里他根本不需要管这些问题。数仓表是建模团队已经优化过的你的任务是在现有表结构上把逻辑写对。如果哪次查询真的慢到影响交付首选方案是加筛选条件缩小数据范围其次找数仓同事沟通而不是自己去做数据库层面的调优。你要建立的心态是数据库调优是开发工程师和 DBA 的专业领域数据分析师是使用者不是维护者。花太多时间在“怎么让查询跑得更快”上就是典型的用战术上的勤奋掩盖战略上的懒惰。3.3 存过、函数、触发器这类开发向内容只需了解即可存储过程在开发场景中很常用但数据分析工作中很少需要你新建一个存储过程。同样的道理适用于触发器和复杂的自定义函数。你需要的是“能读懂别人写的存储过程的大致逻辑”不至于在排查问题时抓瞎但完全没必要精通如何设计一个高效的存储过程。我个人的标准是知道存储过程、触发器、视图、临时表这些对象是干什么的但日常写分析代码时优先使用 WITH 和子查询。这样既不会在团队协作中露怯也不会在无关细节上消耗过多精力。至于那种“用 SQL 实现一个递归查询”的奇怪面试题如果公司不搞数据开发岗你大可以一笑置之。4. 实操案例一个真实业务问题看清以上能力怎么落地前面讲得比较散现在我用一个完整的案例把从拿到业务需求到交付结果的全程走一遍。这个案例是我之前带新人时常用来做能力测评的题目含金量不低。4.1 业务需求与拆解思路先搞清楚“要什么口径”假设业务方丢给你这么一句需求想看一下今年上半年每个月的付费用户中有多少是前一个月没有付过费的“新付费用户”以及这些新付费用户贡献了多少收入按渠道看一下。拿到需求先别急着打开编辑器。先把口径聊清楚“付费用户”的定义是什么是只要产生过付费订单就算还是要求订单状态为“已完成”“前一个月没有付费”的界定怎么处理新用户用户上个月注册但没付费这个月付费算新付费吗我通常的做法是先列出一张口径确认表逐项问清楚把自己对需求的理解用邮件或文档回发给对方确认。这一步在业务方眼里体现的是专业度而不是麻烦。假设对方确认了口径付费用户 产生过状态为成功的订单的用户新付费用户 统计月内有付费行为且往前推 30 天内无任何成功付费订单的用户渠道 用户注册时的渠道。有了明确口径下面拆解就顺畅了。4.2 逐步落地的 SQL 写法从清洗到组装全流程第一步先取出订单表的相关数据。默认数据是脏的先做侦查。-- 侦查订单表有没有重复状态字段有哪些值 SELECT status, COUNT(*) AS cnt FROM orders WHERE order_time 2025-01-01 AND order_time 2025-07-01 GROUP BY status;这一步把状态字段的取值全部列出来看看有没有“失败”“退款”之类的脏值需要排除。再检查一下用户维度有没有重复注册造成的脏数据这里涉及用户表可以用 GROUP BY user_id HAVING COUNT(*) 1 的方式排查。第二步把符合条件的付费行为清洗成一张临时表。WITH paid_orders AS ( SELECT user_id, channel, order_time, order_amount FROM orders WHERE status success AND order_time 2025-01-01 AND order_time 2025-07-01 ),这里把口径中“成功的付费订单”固化下来。紧接着为每个用户每个月的首次付费时间打上标记方便后面做月份维度的聚合。user_first_paid_month AS ( SELECT user_id, channel, DATE_FORMAT(MIN(order_time), %Y-%m) AS first_paid_month FROM paid_orders GROUP BY user_id, channel )第三步判断“新付费用户”。注意我们的定义不是简单看这个用户有没有在前一个月的记录而是要判断该用户在统计月内的首次付费时间距离上一次付费是否超过 30 天。用前面界定的简化版本实现monthly_users AS ( SELECT user_id, DATE_FORMAT(order_time, %Y-%m) AS month, MIN(order_time) AS first_paid_time_in_month FROM paid_orders GROUP BY user_id, DATE_FORMAT(order_time, %Y-%m) )有了这个月粒度表再用窗口函数 LAG 对比上一条付费记录就能知道是不是新鲜用户。-- 用 LAG 取该用户上一次付费时间 with_lag AS ( SELECT *, LAG(first_paid_time_in_month) OVER ( PARTITION BY user_id ORDER BY first_paid_time_in_month ) AS prev_paid_time FROM monthly_users ) SELECT month, channel, COUNT(DISTINCT user_id) AS total_paid_users, COUNT(DISTINCT CASE WHEN prev_paid_time IS NULL OR DATEDIFF(first_paid_time_in_month, prev_paid_time) 30 THEN user_id END) AS new_paid_users FROM with_lag JOIN users ON users.user_id with_lag.user_id GROUP BY month, channel;到这一步整个逻辑链条就完整了先清洗、再做月粒度汇总、再用窗口函数和 CASE WHEN 完成新客判断、最后按渠道汇总。每个环节拆成独立的 CTE一旦结果不对你能精准定位是哪一步出了问题而不是在一个巨型嵌套查询里大海捞针。4.3 结果验证这是最容易被忽略、也最体现功力的环节跑出结果别直接发出去。我要求团队把结果验证当作正式的开发步骤。怎么做呢换一种逻辑用不同的写法验证同一个指标。比如把“新付费用户”数量用 NOT EXISTS 再写一遍看两个思路的结果是否一致。SELECT month, channel, COUNT(DISTINCT user_id) AS new_paid_users_alt FROM monthly_users m WHERE NOT EXISTS ( SELECT 1 FROM paid_orders p WHERE p.user_id m.user_id AND p.order_time m.first_paid_time_in_month AND p.order_time DATE_SUB(m.first_paid_time_in_month, INTERVAL 30 DAY) ) GROUP BY month, channel;两条路径跑出来的数字一致那大概率没问题。如果对不上就说明哪个环节的口径理解有偏差需要你再回头梳理。很多新人没有这个验证习惯出了错还不知道往哪查而老手的“可靠”就是这样一遍遍查出来的。5. 学习路径与日常硬核工具从零到合格需要多久学 SQL 没有捷径但它是一条可以通过正确方法缩短时间的路。下面是一份我多年实践沉淀的路线对零基础或基础不牢的人都有参考价值。5.1 四周时间表每天要做什么做到什么程度我建议普通人脱产或半脱产用四到六周掌握核心技能非脱产则不要拖过两个月。时间拖得越长前面的内容忘得越干净越容易半途而废。第一周解决语法基础。目标是不看资料能写出来 JOIN、LEFT JOIN、WHERE、GROUP BY、ORDER BY、HAVING、聚合函数。这个阶段没有捷径每天至少手写五个查询。第二周进入窗口函数。目标是对 ROW_NUMBER、RANK、DENSE_RANK、LAG、LEAD、SUM OVER 达到比较熟练的程度。这是最难啃的时期解决办法是找真实业务场景反复刷。第三周综合实战。找公开数据集或公司真实脱敏数据模拟业务方提出需求从取数到验证完整走通一天两个需求。第四周习惯养成。带着数据质量意识练习写生产级 SQL要求自己每个查询都有 CTE 拆分、注释和去重检查。四周之后你的水平应该足以应付大多数初级数据分析岗位的 SQL 面试和日常工作了。但要注意学完不等于精通真正的提升是在实际业务里持续使用这个周期因人而异但方向对了时间一定不会白花。5.2 工具选型建议Navicat、DataGrip 和命令行怎么选说到日常写 SQL 的工具DataSource 的选择对效率影响非常大。国内公司最常见的组合是 Navicat 连 MySQL、SQL Server、Oracle 这类数据库。Navicat 的优势是图形化程度高建表、看数据、导数据都方便对新手非常友好。另一个选择是 JetBrains 的 DataGrip它的 SQL 编辑器体验很好代码提示、重构、版本管理都比 Navicat 专业缺点是要适应它的界面。我个人的建议是新手从 Navicat 入手等熟练了可以试试 DataGrip找自己顺手的就行。命令行客户端不是不能用但对数据分析和结果可视化来说没有任何优势日常用 GUI 工具就够了。工作中经常遇到要导出数据的情况学会怎么把查询结果导出成 CSV 或 Excel 格式以及怎么用工具的定时任务来自动跑一些固定的数据报表这些能节省不少日常时间。遇到“无法连接”这类问题时先检查网络、权限、密码三样东西不要盲目重装软件。5.3 用好 AI 但别被 AI 坑生成式 SQL 的正确打开方式这两年 AI 生成 SQL 太火了确实能帮你省不少时间。但这里有一个陷阱很多人把 AI 当作“代写”问一句“帮我写个查询”就直接把结果粘过去用。这是大忌。AI 生成 SQL 的前提是它完全理解你的数据结构和业务口径而这两样它都不可能真正掌握。我曾经让团队做过一个测试给 AI 一张订单表和用户的描述十个查询里它能完全做对的不到一半错的原因几乎都是口径理解偏差。正确用法是把 AI 当“结对编程伙伴”。你先把自己的思路写出来用哪几张表先做什么后做什么用什么条件去关联再把你的思路描述给 AI让它帮你把代码结构整理好或是在你陷入语法障碍时告诉它“我要用窗口函数算出累计值你帮我写个示例”。关键是“你来掌控逻辑它来加速你的打字速度”而不是反过来。数据安全也要留意不要让 AI 工具接触到未脱敏的敏感经营数据。宁可先把表结构拿出来把数据量或者真实字段值遮挡掉再提问。6. 常见问题排查实录那些让新人抓狂的 SQL 经典场景最后这部分我直接整理一份高频问题速查表每个都是我在实际工作和带人过程中踩过的坑看到对应症状直接对号入座就行。6.1 查询结果重复数字虚高这是出现频率最高的问题大多数人第一反应是“难道我 JOIN 写错了”没错十有八九就是 JOIN 引起的。比如订单表和订单明细表一对多关联后订单表的所有字段都被重复复制了导致后续 SUM 金额被放大好几倍。排查方法是先单独跑一遍订单表的汇总和订单明细表的汇总再看关联后的汇总是否和其中之一一致。如果不一致就要先对明细表的粒度要做预聚合把明细先汇总好再 JOIN 主表。这个坑我踩过不止一次现在团队里默认统一遇到多级明细时先聚合再关联避免基数膨胀。6.2 NULL 数据导致计算结果莫名其妙地少SUM 一个包含 NULL 的列NULL 会自动被忽略这通常没问题但如果你用 WHERE 过滤条件比如“筛选状态不是退款”而状态字段里有 NULL这些记录就会因为“NULL 不等于任何值”而被错误地筛掉结果就缺了一块。解决方案是在过滤条件里显式处理 NULL写成WHERE status refunded OR status IS NULL。但要注意不是所有 NULL 都需要保留关键是要知道你业务里 NULL 的含义是什么是三无记录还是有特殊含义。这个判断只能由你结合业务来做。6.3 日期范围判断总是少了那一天这个属于超高频问题。统计“最近 30 天”的数据新人容易直接写WHERE order_time DATE_SUB(CURDATE(), INTERVAL 30 DAY)结果边界时间计算错误把起始当天漏了或者多包含了今天。正确的做法是明确临界点包含今天就要考虑今天的数据还没完全入库不包含今天则用“当前日期”作上限永远不要直接用BETWEEN去包一个动态日期。6.4 大量使用 SELECT * 导致结果不可控且效率低下SELECT * 会把表里所有字段都拖出来数据量大时跑得慢还会掩盖表结构的变动。更麻烦的是同事看到你的 SQL 不知道你到底需要哪些字段后续维护时每次都要去数一遍列。生产级 SQL 的要求就是显式写出需要的字段哪怕多打几个字也不要用 *。6.5 去重方法选错导致数据失真DISTINCT 和 GROUP BY 的去重逻辑不太一样。DISTINCT 是去掉结果集中的重复行适合只查一个字段时的去重GROUP BY 则可以做分组后的去重和聚合计算。很多新人用 DISTINCT 去重后还想去统计数量发现 COUNT(DISTINCT col) 返回的是去重后的数量但其实它是先去重再统计逻辑是对的只是很多人把它和“先统计数量再去重”搞混了。更复杂的问题是两个字段的组合是唯一键但单字段有重复这时要么正确选择到底要按哪个维度去重免得把有效的数据也误删了。6.6 报错信息看不懂不知从何查起常见的报错就那么几类语法错误多了逗号、少了括号、列名不存在拼写或表别名没对上、非聚合列问题GROUP BY 后 select 了没分组的列、数据类型不匹配等。排查顺序建议是先看错误信息定位到行再缩小范围把大查询逐步注释掉来判断问题块最后把报错的片段单独拿出来跑。养成“二分排查法”处理疑难报错会快很多。7. 关于工具和数据安全的一些补充提醒日常使用 SQL 工具时有一个容易被忽略的边界意识需要提醒一下。团队协作中不要在自己的本地电脑上随便安装一些破解版或带激活码来源不明的数据库客户端工具。这类工具在网络上搜索频率极高很多热搜词就是这些内容但用这类工具的风险很大安全漏洞、后门程序都有可能藏身其中。工作中优先使用公司统一采购或授权的正版工具既合规又安全。如果是在自己电脑上学习可以考虑用官方社区版或开源替代品完全足够支撑你练习到能应聘的水平。像 DBeaver、SQL Developer 这些工具都有免费版本不要因为嫌麻烦就走捷径。涉及生产数据的真实表结构永远不要在个人 AI 工具里发送真实的用户明细和经营数据。脱敏之后再提问宁可效率低一点也不要因为一时方便造成数据泄露。这个意识希望你从第一天接触真实数据起就刻在脑子里。最后分享一点个人体会。我带过这么多做数据分析的人SQL 学得怎么样真正拉开的差距不在智商而在“有没有把每次任务当作作品来完成”的习惯。有人写出来的查询别人接手一看思路清晰、注释明白、结果可靠这个人很快就会被信任交付更重要的任务。有人写出来的查询能用但没一个人敢接手。你希望成为哪一种你自己选择。而这道选择题你从今天开始写的第一行 SQL 就在回答它。