公司动态
SQL数据分析7天实战路线:从基础查询到窗口函数与优化
SQL 在数据分析里的地位比很多人想的高。真正进入业务部门后你会发现日常取数、写报表、跑指标大部分工作都在写 SQL。Python 和可视化工具是加分项但 SQL 才是准入门槛。很多同学一上来就啃 pandas、scikit-learn结果面试时手写 SQL 反而卡住这其实很可惜。这套 7 天学习路线把从零基础到完成数据分析项目的过程拆成每天一个主题基础查询、过滤去重、聚合统计、多表关联、函数表达式、窗口函数、项目实战与 SQL 优化。学完后你能独立完成业务报表取数、数据清洗、留存分析、TopN 排行这些高频任务而不是只停留在“看得懂 SELECT”。如果你正准备数据分析岗位面试或者刚开始接触公司里的数据表这篇文章可以直接作为学习清单收藏。1. 核心能力速览项目说明学习主题SQL 数据分析含数据清洗、报表、指标统计学习周期7 天每天一个明确模块前置基础零基础即可需要会基本电脑操作数据库环境MySQL 8.0 / 5.7Docker 部署SQL Server 语法基本兼容核心技能SELECT、WHERE、JOIN、GROUP BY、CASE WHEN、窗口函数进阶方向慢 SQL 优化、索引设计、Python 批量取数、接口服务适合人群数据分析师、数据运营、转行人员、SQL 面试备考者学习工具MySQL、DBeaver、Python、Flask是否支持批量任务支持可用 Python 按目录批量执行 SQL 文件是否支持 API支持可封装成 HTTP 查询接口需做安全控制这套路线不追求一次塞给你几百个函数而是按业务场景去学。第 1 到第 3 天把取数基础打牢第 4 到第 6 天学关联、函数和窗口分析最后一天用订单数据串一遍完整项目同时在项目里学习 EXPLAIN 和索引优化。2. 适用场景与使用边界SQL 数据分析适合这些场景业务部门日常取数比如“上周各区域销售额”。数据清洗比如去重、去空值、统一日期格式。数据报表比如按月统计订单量、客单价、复购率。数据面试笔试或面试中手写 SQL 完成指标分析。数据产品功能开发比如在后台管理系统中执行数据查询。也要说清楚边界。SQL 不擅长做深度机器学习和复杂可视化它负责的是数据提取、聚合和清洗。如果你要做趋势预测、文本分类最终还是要交给 Python 或专门的机器学习平台。可视化可以用 BI 工具或 Python 的 matplotlib、pyecharts但前提是先通过 SQL 把数据算出来。学习过程中要注意合规使用。所有练习数据都建议使用公开数据集或模拟数据。如果在公司里使用真实数据需要遵守数据权限和隐私保护要求不能把用户电话、身份证号等敏感信息导出到个人环境。涉及 SQL 注入攻击这类话题只用于理解风险不能在未授权系统上测试。3. 环境准备与前置条件推荐使用 MySQL 8.0因为它是目前最主流的数据分析数据库语法资料多面试也是高频环境。如果公司用的是 SQL Server逻辑相同只是分页和日期函数略有差异。环境准备分三步。第一步安装 MySQL。最简单的方式是用 Docker 启动避免本机装数据库带来的依赖冲突。Windows 也可以直接安装 MySQL Installer然后在服务管理器里启动服务。下面是 Docker 启动命令。# 使用 Docker 启动 MySQL映射 3306 端口 docker run -d \ --name mysql-data \ -p 3306:3306 \ -e MYSQL_ROOT_PASSWORD123456 \ -e MYSQL_DATABASEsales_analysis \ mysql:8.0等容器启动后检查是否正常。docker ps docker logs mysql-data --tail 50如果看到 MySQL 服务 ready说明启动成功。注意 3306 端口不要和其他本地服务冲突如果冲突就把命令里的3306改成3307:3306。第二步安装数据库客户端。推荐 DBeaver界面清晰支持 MySQL、PostgreSQL、SQL Server 等多种数据库还可以直接在结果集上做图表可视化。安装后新建连接填写主机 127.0.0.1、端口 3306、用户名 root、密码 123456 即可。第三步准备示例表。创建一个简单的业务库包含订单表和用户表方便后续练习。CREATE DATABASE IF NOT EXISTS sales_analysis DEFAULT CHARACTER SET utf8mb4; USE sales_analysis; CREATE TABLE orders ( order_id INT PRIMARY KEY, customer_id INT NOT NULL, product_name VARCHAR(100), category VARCHAR(50), amount DECIMAL(10,2), order_date DATE, region VARCHAR(20) ); CREATE TABLE customers ( customer_id INT PRIMARY KEY, customer_name VARCHAR(50), signup_date DATE );插入一部分模拟数据后面 7 天的练习都基于这些表。INSERT INTO orders (order_id, customer_id, product_name, category, amount, order_date, region) VALUES (1, 1001, 无线鼠标, 数码, 89.00, 2025-01-10, 华东), (2, 1002, 机械键盘, 数码, 299.00, 2025-01-12, 华南), (3, 1001, 显示器, 数码, 1299.00, 2025-02-05, 华东), (4, 1003, 办公椅, 家具, 659.00, 2025-02-18, 华北), (5, 1004, 台灯, 家居, 129.00, 2025-03-02, 华南), (6, 1002, USB 扩展坞, 数码, 159.00, 2025-03-09, 华南), (7, 1005, 文件柜, 家具, 459.00, 2025-03-15, 华东), (8, 1003, 升降桌, 家具, 1599.00, 2025-04-01, 华北); INSERT INTO customers (customer_id, customer_name, signup_date) VALUES (1001, 张三, 2024-12-01), (1002, 李四, 2024-12-15), (1003, 王五, 2025-01-10), (1004, 赵六, 2025-02-20), (1005, 陈七, 2025-03-01);环境准备好后接下来每一天都围绕这套表做练习不要只背语法要动手执行。4. 7 天学习路线从入门到项目实战4.1 Day1基础查询与排序第一天集中解决三个问题怎么把数据查出来怎么按条件过滤怎么排序和限制行数。先看基础查询。-- 查看全部订单 SELECT * FROM orders; -- 只查需要的字段 SELECT order_id, customer_id, amount FROM orders; -- 按金额降序排列 SELECT order_id, customer_id, amount FROM orders ORDER BY amount DESC; -- 只看前 3 条 SELECT order_id, customer_id, amount FROM orders ORDER BY amount DESC LIMIT 3;这一步要理解SELECT列的投影FROM指定表WHERE过滤行ORDER BY排序LIMIT限制结果数量。数据分析中不建议写SELECT *因为业务表可能有很多无用列影响网络传输和下游使用。练习目标查询消费金额大于 100 的订单按订单日期升序排列只看前 5 条。SELECT order_id, customer_id, amount, order_date FROM orders WHERE amount 100 ORDER BY order_date ASC LIMIT 5;执行结果能正常返回即可。如果连接 MySQL 时报错先检查 3306 端口是否开放用户名密码是否正确。4.2 Day2数据过滤与去重第二天重点处理高频业务需求去重、模糊匹配、空值清洗。热搜里经常有人搜“清洗---sql语句去重”和“sql去除空值”其实都是这个模块。去重使用DISTINCT。例如查看订单里出现过哪些区域。SELECT DISTINCT region FROM orders;空值处理用IS NULL和COALESCE。比如客户注册日期为空时给一个默认值。SELECT customer_id, COALESCE(customer_name, 未知用户) AS customer_name FROM customers;过滤条件可以组合。IN适合枚举匹配LIKE适合关键词匹配BETWEEN适合范围匹配。-- 查询华南和华东的订单 SELECT * FROM orders WHERE region IN (华南, 华东); -- 查询商品名称包含“键盘”的订单 SELECT * FROM orders WHERE product_name LIKE %键盘%; -- 查询 2025 年 1 月到 3 月的订单 SELECT * FROM orders WHERE order_date BETWEEN 2025-01-01 AND 2025-03-31;练习目标统计订单表里不重复的客户数。SELECT COUNT(DISTINCT customer_id) AS customer_cnt FROM orders;这里要注意COUNT(DISTINCT 字段)会忽略NULL如果字段本身有空值结果可能偏小。要做到心里有数。4.3 Day3聚合统计与分组第三天进入数据分析最核心的部分聚合。业务指标里的 GMV、订单量、客单价、区域排名都在这一层完成。先看常见聚合函数。SELECT COUNT(*) AS order_cnt, SUM(amount) AS total_amount, AVG(amount) AS avg_amount, MAX(amount) AS max_amount, MIN(amount) AS min_amount FROM orders;这里要区分COUNT(*)和COUNT(column)。COUNT(*)统计行数包含空值行COUNT(column)只统计该列非空值的个数。分组统计是数据分析师每天都要写的几类 SQL 之一。按区域统计销售额。SELECT region, COUNT(*) AS order_cnt, SUM(amount) AS total_amount, AVG(amount) AS avg_order_amount FROM orders GROUP BY region;如果要对聚合后的结果做筛选不能用WHERE要用HAVING。WHERE过滤原始行HAVING过滤分组后的结果。SELECT region, SUM(amount) AS total_amount FROM orders GROUP BY region HAVING SUM(amount) 1000;练习目标按商品品类统计单量、销售额、平均单价找出销售额最高的品类。SELECT category, COUNT(*) AS order_cnt, SUM(amount) AS total_amount FROM orders GROUP BY category ORDER BY total_amount DESC;如果出现only_full_group_by报错是因为 MySQL 默认要求SELECT列表中的非聚合字段必须出现在GROUP BY中。解决办法是确认分组字段是否正确尽量不要只选一个字段而忘记分组。4.4 Day4多表关联与集合操作实际业务里数据不会只放在一张表。用户信息、商品信息、订单信息经常分散在不同表里。第四天专门解决多表关联问题。内连接INNER JOIN只返回两张表都匹配的行。SELECT o.order_id, c.customer_name, o.amount, o.order_date FROM orders AS o INNER JOIN customers AS c ON o.customer_id c.customer_id;左连接LEFT JOIN会保留左表全部行右表没有匹配时返回NULL。比如统计所有用户的订单情况即使用户没有下单也要保留。SELECT c.customer_id, c.customer_name, COUNT(o.order_id) AS order_cnt FROM customers AS c LEFT JOIN orders AS o ON c.customer_id o.customer_id GROUP BY c.customer_id, c.customer_name;多表关联最常踩的坑是一对多导致的数据膨胀。如果customers表和订单表关联一个用户有多个订单COUNT(o.order_id)是正确的但如果你同时关联一个“客户标签表”两边都是多对多数据就会成倍增加。遇到这种场景先单独统计子表再合并。集合操作UNION用于把多个查询结果纵向合并。UNION自动去重UNION ALL不去重性能更好适合确定不会重复的场景。SELECT customer_id FROM customers UNION SELECT customer_id FROM orders;练习目标找出没有下过单的用户。SELECT c.customer_id, c.customer_name FROM customers AS c LEFT JOIN orders AS o ON c.customer_id o.customer_id WHERE o.order_id IS NULL;这个例子是面试高频题也对应真实业务里的“流失用户筛选”。4.5 Day5函数与 CASE WHEN 表达式第五天开始用 SQL 做字段加工这是从“会查数”到“会分析”的关键一步。CASE WHEN是数据分析面试里的常客适合做分组逻辑、阈值分档、标签生成。比如按订单金额分成低、中、高三档。SELECT order_id, amount, CASE WHEN amount 100 THEN 低客单 WHEN amount 500 THEN 中客单 ELSE 高客单 END AS price_level FROM orders;日期函数用于按天、周、月、年聚合。例如计算每个月的销售额。SELECT DATE_FORMAT(order_date, %Y-%m) AS month, SUM(amount) AS total_amount FROM orders GROUP BY DATE_FORMAT(order_date, %Y-%m) ORDER BY month;字符串函数在数据清洗时很常用。SELECT product_name, UPPER(product_name) AS upper_name, LENGTH(product_name) AS name_length, SUBSTRING(product_name, 1, 2) AS left_part, CONCAT([, category, ] , product_name) AS product_full_name FROM orders;空值清洗是数据清洗的另一个重点。比如把空值替换成 0 或“未知”。SELECT COALESCE(region, 未知) AS region_new FROM orders;练习目标给订单打上“工作日单”和“周末单”的标签。SELECT order_id, order_date, CASE WHEN DAYOFWEEK(order_date) IN (1, 7) THEN 周末单 ELSE 工作日单 END AS day_type FROM orders;CASE WHEN可以嵌套也可以和聚合函数配合使用例如统计每个品类的“高客单订单量”占总订单量的比例。4.6 Day6窗口函数与 TopN 分析窗口函数是 SQL 从基础到进阶的分水岭。它可以在不改变行数的情况下计算排名、累计值、移动平均非常适合做业务分析。排名函数最常用的是ROW_NUMBER()、RANK()和DENSE_RANK()。先看每个区域按金额排第几。SELECT order_id, region, amount, ROW_NUMBER() OVER(PARTITION BY region ORDER BY amount DESC) AS rn FROM orders;三个函数的区别ROW_NUMBER()如果金额相同会生成不同编号适合取 TopN。RANK()相同金额排名相同下一名会跳号。DENSE_RANK()相同金额排名相同下一名不跳号。取每个区域销售额最高的前 1 个订单经典写法是子查询加rn。WITH ranked AS ( SELECT order_id, region, amount, ROW_NUMBER() OVER(PARTITION BY region ORDER BY amount DESC) AS rn FROM orders ) SELECT order_id, region, amount FROM ranked WHERE rn 1;累计求和常用于计算“按日累计销售额”。SELECT order_date, SUM(amount) AS day_amount, SUM(SUM(amount)) OVER(ORDER BY order_date) AS cumulative_amount FROM orders GROUP BY order_date ORDER BY order_date;窗口函数还支持ORDER BY和ROWS BETWEEN比如计算最近 3 天平均销售额。SELECT order_date, day_amount, AVG(day_amount) OVER(ORDER BY order_date ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS avg_3d FROM ( SELECT order_date, SUM(amount) AS day_amount FROM orders GROUP BY order_date ) t;练习目标计算每个用户最近一单的金额。WITH r AS ( SELECT order_id, customer_id, amount, order_date, ROW_NUMBER() OVER(PARTITION BY customer_id ORDER BY order_date DESC) AS rn FROM orders ) SELECT customer_id, order_id, amount, order_date FROM r WHERE rn 1;窗口函数在面试中出现频率很高建议单独多写几遍直到能理解PARTITION BY和ORDER BY的执行顺序。4.7 Day7综合项目实战与 SQL 优化最后一天把前面所有知识整合到一个项目里。这里以一个销售订单分析项目为例。项目需求统计 2025 年第一季度的整体销售情况、各区域销售排名、客户复购率并找出 A 类重点客户。先做整体指标。SELECT COUNT(*) AS total_orders, COUNT(DISTINCT customer_id) AS total_customers, SUM(amount) AS total_amount, AVG(amount) AS avg_amount FROM orders WHERE order_date BETWEEN 2025-01-01 AND 2025-03-31;再按区域统计销售额和订单量。SELECT region, COUNT(*) AS order_cnt, SUM(amount) AS total_amount FROM orders WHERE order_date BETWEEN 2025-01-01 AND 2025-03-31 GROUP BY region ORDER BY total_amount DESC;接着计算客户复购率。先统计每个用户的订单次数再判断是否有二次购买。WITH user_orders AS ( SELECT customer_id, COUNT(*) AS order_cnt FROM orders GROUP BY customer_id ) SELECT COUNT(*) AS total_users, SUM(CASE WHEN order_cnt 2 THEN 1 ELSE 0 END) AS repeat_users, SUM(CASE WHEN order_cnt 2 THEN 1 ELSE 0 END) / COUNT(*) AS repeat_rate FROM user_orders;最后做一个简单的 RFM 模型用最近一次下单时间和累计消费金额给客户分层。WITH stats AS ( SELECT customer_id, MAX(order_date) AS last_order_date, DATEDIFF(2025-06-01, MAX(order_date)) AS recency, COUNT(*) AS frequency, SUM(amount) AS monetary FROM orders GROUP BY customer_id ) SELECT customer_id, CASE WHEN recency 30 AND monetary 500 THEN 重点客户 WHEN recency 60 THEN 潜力客户 ELSE 预警客户 END AS customer_level FROM stats;项目做完后还要验证一条大表查询是否高效。这就是 SQL 优化的切入点。对上面的查询执行EXPLAIN如果发现全表扫描就考虑给customer_id、order_date建索引。CREATE INDEX idx_orders_customer_id ON orders(customer_id); CREATE INDEX idx_orders_order_date ON orders(order_date);5. 接口 API 与批量任务学习路线跑通后下一步是工程化。实际工作里SQL 很少只在客户端里手敲更多是写进脚本、定时任务或接口服务里。5.1 Python 连接 MySQL用pymysql连接数据库再配合pandas直接读取结果。import pymysql import pandas as pd conn pymysql.connect( host127.0.0.1, userroot, password123456, databasesales_analysis, charsetutf8mb4 ) sql SELECT region, COUNT(*) AS order_cnt, SUM(amount) AS total_amount FROM orders GROUP BY region ORDER BY total_amount DESC df pd.read_sql(sql, conn) print(df) conn.close()这一步能直接把 SQL 结果变成 DataFrame后续交给 Python 做图表或建模就比较方便。5.2 参数化查询防注入使用外部输入组合 SQL 时不能直接拼接字符串否则会产生 SQL 注入风险。热搜里经常有人搜索“sql注入万能密码绕过”这属于安全攻击话题普通开发者要做的是正确防御。正确写法是用参数化查询。sql SELECT * FROM orders WHERE customer_id %s df pd.read_sql(sql, conn, params(1001,))不要写成下面这种。# 危险写法禁止在真实项目中这样拼 SQL customer_id 1001 or 11 sql SELECT * FROM orders WHERE customer_id customer_id df pd.read_sql(sql, conn)参数化查询会交给数据库驱动转义是避免 SQL 注入的基本手段。5.3 批量执行 SQL 文件需要一次性跑多个分析脚本时可以写一个批处理脚本按目录依次执行 SQL 文件。import os import pymysql conn pymysql.connect( host127.0.0.1, userroot, password123456, databasesales_analysis, charsetutf8mb4 ) sql_dir ./sql_tasks cursor conn.cursor() for file_name in os.listdir(sql_dir): if not file_name.endswith(.sql): continue file_path os.path.join(sql_dir, file_name) with open(file_path, r, encodingutf-8) as fp: script fp.read() for statement in script.split(;): statement statement.strip() if statement: cursor.execute(statement) conn.commit() print(fexecuted: {file_name}) cursor.close() conn.close()批量任务要注意两点一是不能把整文件直接execute因为 MySQL 驱动默认不支持多语句二是要给每个脚本加日志和异常捕获避免一个报错导致整个任务中断。5.4 封装成 HTTP 接口如果其他系统需要调用分析结果可以封装成只读 API。注意接口必须做鉴权和 SQL 白名单不能把任意 SQL 暴露给外部。from flask import Flask, request, jsonify import pymysql import pandas as pd app Flask(__name__) ALLOWED_SQL { region_sales: SELECT region, SUM(amount) AS total_amount FROM orders GROUP BY region, category_sales: SELECT category, COUNT(*) AS cnt, SUM(amount) AS total_amount FROM orders GROUP BY category } def get_data(sql): conn pymysql.connect( host127.0.0.1, userroot, password123456, databasesales_analysis, charsetutf8mb4 ) df pd.read_sql(sql, conn) conn.close() return df app.route(/query, methods[POST]) def query(): token request.headers.get(X-Token) if token ! your-secret-token: return jsonify({error: unauthorized}), 401 payload request.get_json() query_key payload.get(key) if query_key not in ALLOWED_SQL: return jsonify({error: query not allowed}), 400 df get_data(ALLOWED_SQL[query_key]) return jsonify(df.to_dict(orientrecords)) if __name__ __main__: app.run(host127.0.0.1, port5000)这种白名单方式比直接传 SQL 安全很多。如果要传动态参数可以使用params元组但一定要先做参数白名单校验。6. 资源占用与性能观察数据分析项目做到后期数据量会快速增长查询变慢是必然现象。学会定位慢 SQL是独立研究问题的高级能力。6.1 用 EXPLAIN 定位慢查询在 SQL 前加EXPLAIN可以查看执行计划。EXPLAIN SELECT * FROM orders WHERE customer_id 1001;重点看这几列typeALL表示全表扫描ref或range表示用到索引。rows预计扫描的行数越小越好。Extra如果出现Using filesort或Using temporary通常需要优化排序或去重。没有索引时type通常是ALL。建立索引后再看会变成ref或range。CREATE INDEX idx_orders_customer_id ON orders(customer_id); EXPLAIN SELECT * FROM orders WHERE customer_id 1001;6.2 索引不是越多越好索引能加速查询但写入和更新会变慢。数据分析场景里重点是给高频过滤字段和关联字段建索引。实际优化原则给WHERE里的字段建索引。给JOIN ON的字段建索引。给ORDER BY、GROUP BY的字段考虑索引。不要在索引列上做函数运算否则索引失效。避免SELECT *只取需要字段降低网络和内存压力。6.3 使用慢查询日志MySQL 可以开启慢查询日志自动记录执行时间超过阈值的 SQL。SET GLOBAL slow_query_log ON; SET GLOBAL long_query_time 1; SHOW VARIABLES LIKE slow_query_log;分析时可以从日志里抓到耗时超过 1 秒的 SQL再逐条用EXPLAIN检查。这个过程能明显提升数据提取效率。6.4 观察执行时的系统占用当 SQL 卡住时可以通过数据库的SHOW PROCESSLIST查看当前会话。SHOW FULL PROCESSLIST;如果发现大量长时间运行的SELECT判断是索引缺失还是数据量过大。对于超大分析任务可以拆成多个小批次或者把结果写入中间表再聚合避免一次任务占用过多 IO 和内存。7. 常见问题与排查方法学习 SQL 数据分析时遇到报错是正常的。下面的表格整理了最常见的几类问题。问题现象可能原因排查方式解决方案连接不上 MySQL服务未启动或端口被占用docker ps查看容器状态检查 3306 端口启动容器或修改端口映射中文显示乱码字符集不是 utf8mb4查看连接参数和表字符集连接参数加charsetutf8mb4建表指定utf8mb41064语法错误SQL 关键字拼写或逗号位置错误检查错误信息定位报错位置逐行检查 SQL删除多余逗号1054字段不存在字段名拼写错误或表里没有该字段执行DESC 表名查看字段修正字段名only_full_group_by报错SELECT 的非聚合字段没出现在 GROUP BY检查 GROUP BY 字段是否完整把所有非聚合字段加入 GROUP BY查询结果为空数据条件太严格或存在隐藏空格去掉部分条件测试用LIKE模糊匹配检查数据质量确认过滤条件LEFT JOIN 后数据翻倍关联字段有重复值导致一对多对关联字段做去重统计先聚合子表再关联主表SQL 查询非常慢没有索引或数据量过大用EXPLAIN查看扫描行数建索引限制查询范围优化 JOIN 顺序API 返回不支持 JSONDataFrame 里有 datetime 类型打印df.dtypes查看先转换为字符串再返回 JSON排查问题的核心是拆分。不要盯着整条 SQL 看先把WHERE去掉跑一遍再一步步加条件很快就能定位问题。8. 最佳实践与使用建议学习完 7 天路线后建议在日常工作中遵守一套稳定实践减少返工。SQL 书写规范。关键字统一大写字段统一小写表名和字段都要有明确含义。orders比od可读性高很多。复杂查询保留缩进和注释方便团队其他人接手。数据清洗要提前。去重、去空值、格式统一尽量在 SQL 阶段完成不要等导出到 Excel 再处理。比如DISTINCT、COALESCE、DATE_FORMAT都是高效清洗手段能在源头解决大部分脏数据问题。查询时只取必要字段和行数。开发阶段先LIMIT 100确认逻辑正确后再去掉限制。不要每次手滑跑SELECT *处理千万级大表。接口服务必须控制权限。不要开放任意 SQL 接口使用白名单、只读账号和 Token 鉴权。这一点在分析系统开发中非常重要也是网络搜索里“sql注入”相关风险的主要教训。批量任务要留日志。按时间戳记录执行状态、影响行数、错误信息。这样任务失败时能快速定位。数据合规不能忽略。做 SQL 数据分析时使用的数据必须来自合法授权渠道。涉及用户隐私的数据导出前要脱敏。涉及人脸、声音、个人信息的内容要严格遵守隐私保护要求。9. 总结与下一步这套 7 天路线最大的价值是把 SQL 数据分析需要频繁使用的知识点压缩成一个递进顺序避免你在众多 SQL 函数里迷失方向。从每日取数到报表统计再到窗口函数和项目实战每一步都有可执行代码和练习目标。最先要验证的是基础查询和聚合分组因为它们是日常取数最高频的部分。最容易踩的坑是多表关联时数据膨胀以及空值处理不仔细导致统计结果偏小。第 7 天的项目实战可以作为一次自测如果能在不使用搜索引擎的情况下完成订单分析和 RFM 分层说明核心语法已经过关。后续可以继续扩展的方向有索引失效场景、执行计划深度分析、Python 定时调度、BI 报表自动化以及从 SQL 到数据仓库的分层建模。建议把这套内容加入收藏每隔一段时间重新用真实业务数据练一遍熟练度提升会非常快。