京公网安备 11010802034615号
经营许可证编号:京B2-20210330
你有没有想过,手机里点外卖、刷社交软件、转一笔账,背后到底是谁在替你"记着账"?
答案其实很简单:数据库,以及跟它对话的那门语言——SQL。
这篇文章就是为完全没接触过数据库的你写的。跟着读下去,你会明白 SQL 到底是什么、为什么它和 Python、JavaScript 不一样、最常用的几条命令怎么写,以及怎样用 4 周时间从零基础练到能应付大多数技术面试。
SQL(Structured Query Language,结构化查询语言)是用来和数据库"说话"的语言。
几乎所有存数据的应用,背后都跑着 SQL——社交平台、银行系统,甚至是你中午用来点午餐的那个 App。
和大多数编程语言不同,SQL 不负责画界面,也不负责写算法。它的使命很纯粹:向数据提问,并得到精确的答案。
只要你能用中文把问题说清楚,你就能学会用 SQL 把它"翻译"出来。
如果你学过 JavaScript 或 Python,刚接触 SQL 会觉得它"怪怪的"。但恰恰是这种"怪",对初学者非常友好。
SQL 是声明式的语言:你描述"想要什么",而不是"怎么得到它"。
在 JavaScript 里,你可能会写一个循环去过滤数组;在 SQL 里,你只要写一句 WHERE 条件,剩下的"怎么高效找到这些行"交给数据库自己去操心。
这让 SQL 在很多方面都更好学。基本操作都很直观,语法读起来几乎像英语:
SELECT name, email
FROM users
WHERE age > 25
ORDER BY name;
就算你完全不懂 SQL,大概也能猜出这句在干嘛:把 25 岁以上用户的姓名和邮箱取出来,按字母顺序排列。
你这辈子会写到的每一条 SQL 查询,几乎都是由下面这五个操作搭出来的。把它们练熟,绝大多数数据问题你都能答上来。
SELECT 用来指定你想看哪些列。
-- 取出所有列
SELECT * FROM products;
-- 只取特定列
SELECT name, price FROM products;
-- 给输出列改个名字
SELECT name AS product_name,
price AS unit_price
FROM products;
WHERE 把结果缩小到符合某个条件的行。
-- 精确匹配
SELECT * FROM users WHERE city = 'New York';
-- 大小比较
SELECT * FROM products WHERE price > 50;
-- 多个条件
SELECT * FROM users
WHERE age >= 18 AND city = 'London';
-- 模糊匹配
SELECT * FROM users
WHERE email LIKE '%@gmail.com';
-- 列表匹配
SELECT * FROM orders
WHERE status IN ('pending', 'processing');
真实的数据库会把数据分散在多张表里,JOIN 负责把它们合到一起。
想象有两张表:users(id, name, email)和 orders(id, user_id, total, date)。想看"谁买了什么":
SELECT users.name, orders.total, orders.date
FROM users
JOIN orders ON users.id = orders.user_id;
上面这是 INNER JOIN(内连接),只显示至少下过一单的用户。如果你想看到所有用户、包括没下过单的:
SELECT users.name, orders.total
FROM users
LEFT JOIN orders ON users.id = orders.user_id;
没有订单的用户,在 total 这一列会显示 NULL。
GROUP BY 把行"折叠"成一个个分组,让你能计算聚合结果。
-- 统计每个城市的用户数
SELECT city, COUNT(*) AS user_count
FROM users
GROUP BY city;
-- 每个客户的平均订单金额
SELECT user_id, AVG(total) AS avg_order
FROM orders
GROUP BY user_id;
-- 每个月的营收总额
SELECT DATE_TRUNC('month', date) AS month,
SUM(total) AS revenue
FROM orders
GROUP BY DATE_TRUNC('month', date)
ORDER BY month;
ORDER BY 负责安排输出的顺序。
-- 按字母排
SELECT * FROM users ORDER BY name;
-- 价格从高到低
SELECT * FROM products ORDER BY price DESC;
-- 多个排序键
SELECT * FROM users ORDER BY city, name;
-- 只取前 10 条
SELECT * FROM products
ORDER BY price DESC
LIMIT 10;
初学者最容易犯的错,就是想一口气写出一条超复杂的查询。正确的做法,是一层一层往上叠:
问题:"2025 年总营收最高的前 5 个城市是哪些?"
第 1 步:先看原始数据。
SELECT * FROM orders;
第 2 步:筛出 2025 年的。
SELECT * FROM orders
WHERE date >= '2025-01-01' AND date < '2026-01-01';
第 3 步:连上 users 表,拿到城市信息。
SELECT users.city, orders.total
FROM orders
JOIN users ON orders.user_id = users.id
WHERE orders.date >= '2025-01-01'
AND orders.date < '2026-01-01';
第 4 步:按城市分组,把金额加起来。
SELECT users.city, SUM(orders.total) AS revenue
FROM orders
JOIN users ON orders.user_id = users.id
WHERE orders.date >= '2025-01-01'
AND orders.date < '2026-01-01'
GROUP BY users.city;
第 5 步:排序并取前 5。
SELECT users.city, SUM(orders.total) AS revenue
FROM orders
JOIN users ON orders.user_id = users.id
WHERE orders.date >= '2025-01-01'
AND orders.date < '2026-01-01'
GROUP BY users.city
ORDER BY revenue DESC
LIMIT 5;
每一步都能单独运行、验证结果是否合理,再往上加下一层。这种"搭积木"的写法,比憋大招稳得多。
WHERE 是在分组之前过滤单行;HAVING 是在分组之后过滤分组。
-- 错:WHERE 不能直接用聚合函数
SELECT city, COUNT(*) FROM users
WHERE COUNT(*) > 10
GROUP BY city;
-- 对:用 HAVING 在 GROUP BY 之后过滤
SELECT city, COUNT(*) FROM users
GROUP BY city
HAVING COUNT(*) > 10;
NULL 不等于 0,也不等于空字符串。它表示"未知"或"缺失"。
-- 这样查不到 phone 为 NULL 的行(错误!)
SELECT * FROM users WHERE phone = NULL;
-- 正确写法
SELECT * FROM users WHERE phone IS NULL;
两张表都有同名列时,必须指明你指的是哪张表的列。
-- 有歧义(到底是哪个 id?)
SELECT id, name FROM users JOIN orders ON users.id = orders.user_id;
-- 写清楚
SELECT users.id, users.name FROM users JOIN orders ON users.id = orders.user_id;
别名让查询更短、更易读,尤其在 JOIN 多张表时。
-- 不用别名(啰嗦)
SELECT users.name, orders.total
FROM users
JOIN orders ON users.id = orders.user_id;
-- 用别名(清爽)
SELECT u.name, o.total
FROM users u
JOIN orders o ON u.id = o.user_id;
同样是 SQL,不同岗位用起来侧重点不一样。
数据分析师主要用 SQL 来:
核心技能:复杂的 JOIN、窗口函数、CTE(公用表表达式)、日期处理、聚合。
后端开发主要用 SQL 来:
不管你走哪条路,基本功都是一样的。把 SELECT、WHERE、JOIN、GROUP BY、ORDER BY 学透,两条路的地基就都打好了。
第 1 周:SELECT 和 WHERE
第 2 周:JOIN
第 3 周:聚合
第 4 周:子查询与进阶

你有没有想过,手机里点外卖、刷社交软件、转一笔账,背后到底是谁在替你"记着账"? 答案其实很简单:数据库,以及跟它对话的那 ...
2026-10-07CDA数据分析师 出品 作者:李诗怡 一、数据分析四大思维 1. 对比思维:没有对比就没有分析 核心观点:单独一个数字没有意义,有 ...
2026-10-05Kimball 是方法,星型模型是它产出的形状。 很多人把"Kimball vs 星型模型"当成一道选择题——这本身就是个误会:Kimball 是动词 ...
2026-10-05写在开头 老板在微信上甩来一句: "帮我看下为什么销量跌了。" ” 你回工位,打开 SQL,开始写。查订单表、拉近三个月、按 ...
2026-10-03CDA数据分析师 出品 作者:李诗怡 1. 事实表 vs 维度表 对比维度 事实表 维度表 核心问题 记录“业务发生了什么事” 描述 ...
2026-10-02做数据聚合时,PySpark的groupBy()确实能完成统计,这也是它的本职工作。但它有一个根本性局限:每一组数据,最终只能返回一行 ...
2026-10-01热力地图是数据可视化中极具辨识度与实用性的空间分析图表,结合地理空间维度与数据密度特征,通过颜色深浅、色阶渐变直观展示数 ...
2026-09-30 很多数据分析师做过按月份的销售额趋势图,画过按天的流量折线图,但当被问到“时间序列和普通数据有什么本质区别”“季节性 ...
2026-09-30同样是“银行数据岗”,在国有大行总行数据中心、在一家城商行的零售部、在银行系金融科技子公司、在保险公司,工作内容、成长节 ...
2026-09-29在数据分析与统计学研究中,数据往往不是独立存在的,不同变量之间普遍存在相互关联、相互影响的关系。相关性统计分析是挖掘变量 ...
2026-09-29 导读:大多数人只把 dataclasses 当成偷懒工具,用来少写 __init__、__repr__ 这类魔法方法。但它的能力远不止于此。本文带 ...
2026-09-29 很多数据分析师能熟练地计算指标、搭建标签体系,但当被问到“画像到底在解决什么问题”“画像和标签是什么关系”“画像如何 ...
2026-09-29在MySQL数据库运维与业务开发中,行业普遍存在“数据达到千万级就必须分表”的说法。但在实际生产环境中,千万条数据并不是强制 ...
2026-09-28CDA数据分析师 出品 作者:李诗怡 1. 5W1H 分析法 定义:经典系统性思维框架,通过六个核心维度对问题进行全方位拆解与剖析,确 ...
2026-09-28 很多分析师在设计标签时思路清晰,但真到落地环节却面临“数据在手,不知如何转化为可用标签”的困境:或因加工方式选择不当 ...
2026-09-28CDA数据分析师 出品 作者:李诗怡 1. 用户标签体系 定义: 通过一系列高度精炼的特征标识,对用户属性、行为与偏好进行量化刻画 ...
2026-09-24Pandas是Python生态中用于表格数据处理的核心库,广泛应用于数据清洗、统计运算、报表输出、数据分析建模等场景。在处理极大数值 ...
2026-09-24随着数字经济快速发展,数据已成为核心生产要素,各行各业的业务沉淀、用户行为、设备运行、市场交易均产生海量数据。数据处理作 ...
2026-09-24 很多分析师每天和数据打交道,但当被问到“标签是什么”“标签和指标有什么区别”“标签体系如何设计”时,却常常答不上来。 ...
2026-09-24在时序数据分析中,大部分业务数据并非持续平稳变化,而是会在某些时间节点出现突然抬升、断崖下跌、趋势反转、波动异变等现象, ...
2026-09-23