原文链接:https://www.hisqlboy.com/blog/first-sql-query-select-where-group-by
适合人群:SQL 初学者、刚开始写查询的开发者、数据分析入门用户
很多人刚学 SQL 时,都会遇到一个很真实的问题:
别人写好的 SQL 勉强能看懂,但让自己从空白编辑器里写一条查询,脑子就会突然空掉。
明明知道 SELECT、WHERE 这些关键字,也知道数据库里有表、有行、有列,但真正开始写的时候,还是不知道第一步该写什么,第二步该接什么。
这篇文章就解决这个问题。
你不需要一开始就学很复杂的语法。先把最常用的 4 个子句理顺:
SELECTWHEREORDER BYGROUP BY
只要把这四个东西的作用和顺序想清楚,大多数入门查询就已经能写出来了。
1. 为什么你能看懂 SQL,却不一定会自己写
因为"看懂 SQL"和"从头写 SQL"其实是两种不同的能力。
看别人写好的 SQL,有点像看一道已经做完的数学题。
你能顺着它的逻辑往下读,但这不代表你已经掌握了从题目到答案的完整思考过程。
比如下面这个问题:
客户 1 有哪些订单?
它背后其实藏着好几个决定:
- 你要显示哪些列?
- 你要保留哪些行?
- 结果要不要排序?
如果问题再换成:
每个客户分别有多少订单?
那思路又变了。
这已经不是简单"列出数据",而是"把数据汇总起来",于是 GROUP BY 就出现了。
所以要真正学会写 SQL,关键不是背关键字,而是把问题拆成步骤。
2. 把一条 SQL 当成"向数据表提问"
有一个很实用的理解方式:
SELECT:我要看什么?FROM:我要从哪张表里拿?WHERE:哪些行要留下,哪些行要过滤掉?ORDER BY:结果要按什么顺序排?GROUP BY:哪些重复的行需要合并成一个汇总结果?
这样理解之后,SQL 就不再像一串死板语法,而更像你在一步一步问数据库问题。
来看两个例子:
- 问题 A:显示所有订单
- 问题 B:统计每个客户有多少订单
问题 A 是"列出记录",问题 B 是"汇总记录"。
这就是为什么问题 B 需要 GROUP BY,而问题 A 不需要。
3. 先学最常用的 4 个 SQL 子句
3.1 SELECT:先决定你想看什么
最简单的查询就是直接从表里取列:
sql
SELECT order_id, customer_id, order_date
FROM b2_orders;
这条 SQL 的意思很直接:
从 b2_orders 表中,取出 order_id、customer_id、order_date 这三列。
它没有过滤,也没有排序,本质上就是"把这张表里我关心的几列展示出来"。
所以你可以先记住:
SELECT 解决的是"我要看哪些字段"。`
4. WHERE:再决定你要哪些行
如果你不想看全部订单,只想看客户 1 的订单,就要加 WHERE:
sql
SELECT order_id, customer_id, order_date
FROM b2_orders
WHERE customer_id = 1;
这条语句的意思是:
- 先从
b2_orders里拿出三列 - 但只保留
customer_id = 1的那些行
这一步很好理解,因为它本质上就是"加条件过滤"。
所以:
WHERE 解决的是"哪些行应该留下"。`
5. ORDER BY:让结果按你希望的方式排列
如果你还想把客户 1 的订单按时间倒序排列,也就是最新订单排在最前面,可以这样写:
sql
SELECT order_id, customer_id, order_date
FROM b2_orders
WHERE customer_id = 1
ORDER BY order_date DESC;
这里的重点是:
ORDER BY order_date表示按订单日期排序DESC表示降序,也就是从新到旧
如果写成 ASC,就是升序,从旧到新。
很多初学者会把排序和分组搞混,但这两者完全不是一回事:
ORDER BY只是改变已有结果的顺序GROUP BY会改变结果的粒度
这一点后面很关键。
6. GROUP BY:当问题从"列出数据"变成"统计数据"
如果你的问题变成:
每个客户各有多少订单?
这时就不能再简单列出每条订单了,因为你想看的已经不是"订单明细",而是"客户维度的汇总结果"。
这时候就该用 GROUP BY:
sql
SELECT
customer_id,
COUNT(*) AS total_orders
FROM b2_orders
GROUP BY customer_id
ORDER BY total_orders DESC;
这条 SQL 的含义是:
- 按
customer_id分组 - 统计每个客户的订单数
- 按订单数从高到低排序
你可以把 GROUP BY 理解成:
把相同的值装进同一个桶里,然后对每个桶做统计。
在这条查询里:
- 桶是客户
- 统计方式是
COUNT(*)
7. SELECT、WHERE、ORDER BY、GROUP BY 到底怎么串起来
如果你总觉得这些子句是零散的,不妨把它们看成一条完整的思路链:
- 我要看什么结果?
- 数据从哪张表来?
- 要不要先过滤?
- 是列出明细,还是做汇总?
- 最终结果怎么排序?
举个例子。
问题:列出客户 1 的订单,并按时间倒序排
sql
SELECT order_id, customer_id, order_date
FROM b2_orders
WHERE customer_id = 1
ORDER BY order_date DESC;
这是"明细型"问题。
问题:统计每个客户有多少订单
sql
SELECT customer_id, COUNT(*) AS total_orders
FROM b2_orders
GROUP BY customer_id
ORDER BY total_orders DESC;
这是"汇总型"问题。
你在写 SQL 时,只要先分清楚自己面对的是哪一类问题,思路就会清楚很多。
8. 初学者最容易混淆的一点:排序不是分组
这是入门阶段特别常见的误区。
很多人以为 GROUP BY 只是更高级的 ORDER BY,其实完全不是。
ORDER BY 做了什么
它只是把原本已经存在的行重新排个顺序。
比如你有 5 条订单记录,用 ORDER BY 之后,还是 5 条订单记录,只是顺序不同了。
GROUP BY 做了什么
它会把多条明细行压缩成更粗粒度的结果。
比如原来是"一条订单一行",按客户分组之后,结果就变成了"一个客户一行"。
这就是所谓的结果粒度变化。
一旦你理解了这点,很多 SQL 错误都会更容易看懂。
9. 写 SQL 时,一套适合初学者的思考顺序
虽然 SQL 写出来的顺序通常是:
sql
SELECT ...
FROM ...
WHERE ...
GROUP BY ...
ORDER BY ...
但你脑子里的思考顺序不一定非得一样。
更适合初学者的方式是:
- 先想清楚结果长什么样
- 再确定数据来自哪张表
- 再判断是否要过滤行
- 再判断是否要做汇总
- 最后决定怎么排序
这个顺序的好处是,你不容易一上来就冲着 GROUP BY 或 ORDER BY 去写,而忘了自己到底想查什么。
10. 一个简单的 SQL 入门练习方法
如果你刚开始学 SQL,可以按下面的顺序自己练:
练习 1:只写 SELECT
sql
SELECT order_id, customer_id, order_date
FROM b2_orders;
目标:先习惯"从表里拿列"。
练习 2:加 WHERE
sql
SELECT order_id, customer_id, order_date
FROM b2_orders
WHERE customer_id = 1;
目标:理解"按条件筛选行"。
练习 3:再加 ORDER BY
sql
SELECT order_id, customer_id, order_date
FROM b2_orders
WHERE customer_id = 1
ORDER BY order_date DESC;
目标:理解"结果如何排序"。
练习 4:最后加 GROUP BY
sql
SELECT customer_id, COUNT(*) AS total_orders
FROM b2_orders
GROUP BY customer_id
ORDER BY total_orders DESC;
目标:理解"什么时候该从明细切换到汇总"。
这样一步一步练,比一上来就写复杂查询更有效。
11. 总结
SQL 入门阶段最重要的,不是一次性记住很多语法,而是先建立一条稳定的写查询思路:
SELECT:看什么FROM:从哪里看WHERE:筛哪些行GROUP BY:要不要汇总ORDER BY:结果怎么排
当你能把这几个问题顺着想清楚时,空白编辑器就不会那么可怕了。
从这个角度看,写 SQL 其实不是在拼关键字,而是在把一个问题拆成几个可以执行的步骤。
延伸阅读
- 原文:https://www.hisqlboy.com/blog/first-sql-query-select-where-group-by
- SQL 表、行、列、主键入门:https://www.hisqlboy.com/blog/understanding-sql-tables-rows-columns-and-keys
- SQL 数据分析入门:https://www.hisqlboy.com/blog/sql-data-analysis-for-beginners
- ORDER BY 详解:https://www.hisqlboy.com/blog/sql-order-by-and-limit