十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SQL入门到进阶:一篇搞懂数据库查询语言的核心用法

SQL入门到进阶:一篇搞懂数据库查询语言的核心用法 读过这篇文章你大概能搞懂 SQL 到底是什么以及它凭什么能成为现代数据处理绕不开的一门语言。我会用最容易理解的方式把 SQL 的核心能力和常见使用场景拆开来讲也会穿插一些实际工作中踩过的坑。如果你是刚准备转行做数据分析、后端开发的初学者或者工作中经常要和数据库打交道但一直没系统梳理过 SQL 的用法这篇文章应该能帮你建立一张完整的地图从 SQL 是什么到它能做什么再到怎么快速上手一次讲清楚。1. SQL 到底是什么一门专门跟数据打交道的语言1.1 SQL 不是数据库而是操作数据库的通用语言很多人第一次听到 SQL 的时候会把它和 MySQL、SQL Server、Oracle 这些词混在一起以为 SQL 就是一个数据库软件。其实不是SQLStructured Query Language结构化查询语言是一种标准化的计算机语言专门用来管理和操作关系型数据库。你可以把 SQL 理解成“数据库世界里的普通话”MySQL、SQL Server、Oracle、PostgreSQL 这些数据库产品就像不同地区的人虽然各自有各自的方言和习惯但只要你用普通话SQL 标准它们基本都能听懂。举个更生活的例子。如果把数据库比作一个大型仓库里面堆满了各种各样的货物数据SQL 就是一套统一的“仓库管理指令”。你想知道仓库里有哪些货输入一条“查一下”的指令你想往仓库里加一箱新货输入一条“放进去”的指令你想把某个货架上的旧数据换掉再输入一条“改一下”的指令。这套指令不是某个仓库私有发明的而是整个行业约定好的规则所以你在 A 仓库学会的指令到了 B 仓库同样能用只是个别仓库可能会有些自己的快捷键。这个区分很重要。很多人刚开始学 SQL 时困惑“我应该学 MySQL 还是 SQL Server”其实你真正要学的是 SQL 这门语言本身。MySQL 和 SQL Server 只是承载这门语言的工具学会了标准的 SQL再花半天到一天时间去熟悉某个具体工具的差异就能很快上手。1.2 SQL 的语法家族不只是查询还有不少人把 SQL 理解成“select from where”觉得 SQL 不就是查数据吗这也是一大误区。SQL 其实是一个语法家族涵盖了对数据的完整操作周期。日常使用中最常见的是四类数据查询语言DQL核心就是 SELECT负责把数据查出来。这是绝大多数人用得最多、也最看重的一块。数据操作语言DML包括 INSERT、UPDATE、DELETE负责新增、修改、删除数据。数据定义语言DDL包括 CREATE、ALTER、DROP负责定义和修改数据库表结构相当于规划仓库里建几个货架、每个货架放什么货。数据控制语言DCL包括 GRANT、REVOKE负责控制谁能访问、谁能操作相当于仓库的门禁系统。我见过不少从数据分析入门 SQL 的朋友学了半年只用了 SELECT后来工作中要临时整理一批数据需要建一张临时表才发现自己连 CREATE TABLE 都写不利索。其实 SQL 的整体框架并不复杂四类语法各有明确分工学的时候按这个框架去梳理会清晰得多。2. SQL 能做什么从最简单的增删改查说起2.1 把数据放进去INSERT假设你在做一个小型电商项目用户下了一笔订单你要把这个订单信息存进数据库用的就是 INSERT 语句。比如有一张订单表 orders包含订单编号 order_id、用户编号 user_id、商品编号 product_id、金额 amount、下单时间 create_time 这几个字段插入一条订单记录的语句大致长这样INSERT INTO orders (order_id, user_id, product_id, amount, create_time) VALUES (20250101001, 1001, 5002, 299.00, 2025-01-01 10:30:00);这里有个很常见的坑INSERT 时字段顺序必须和 VALUES 里的值一一对应或者干脆在语句里写明字段名否则很容易把数据插错位置。我见过一个同事插入数据时没写字段名结果把 299.00 这个金额塞进了 user_id 那一列隔了好几天查账才对不上排查半天才找到原因。所以我的建议是无论表结构多简单INSERT 语句都尽量把字段名写全多打几个字换来的安全非常划算。2.2 把数据拿出来SELECT 的花样最多SELECT 是 SQL 里最核心、也最长见识的一条命令。它不光是“把表打印出来”那么简单你可以在它后面叠加各种子句把数据加工成你想要的形态。比如你想查订单表里今天所有订单但不想看全部字段只想看用户编号和金额就可以指定字段查询SELECT user_id, amount FROM orders WHERE create_time 2025-01-01 00:00:00;如果同一个用户下过很多订单你想看看有哪些不同的用户下过单不想重复显示那就用 DISTINCT 去重SELECT DISTINCT user_id FROM orders;新手最容易在这个地方犯迷糊DISTINCT 的作用范围是多列组合。比如你写SELECT DISTINCT user_id, order_id FROM orders它去重的是 user_id 和 order_id 的组合而不是只看 user_id。如果你只想看有多少个不同的用户写SELECT DISTINCT user_id就好千万别画蛇添足。如果你想统计每个用户一共下了多少单、总金额多少那就轮到聚合函数和 GROUP BY 出场SELECT user_id, COUNT(*) AS order_cnt, SUM(amount) AS total_amount FROM orders GROUP BY user_id ORDER BY total_amount DESC;这条语句背后的逻辑是先把订单按 user_id 分成一组一组的然后用 COUNT 数每组里有多少行用 SUM 累加每组的金额。这是 SQL 做数据分析时最基础也最常用的统计思路。掌握了这个你已经能回答很多业务问题了比如“每天有多少新用户注册”“每个分类的商品销售额是多少”。2.3 把数据改掉或删掉UPDATE 和 DELETEUPDATE 用来修改已有数据。比如用户申请退款你要把订单状态从“待付款”改成“已取消”UPDATE orders SET status 已取消 WHERE order_id 20250101001;DELETE 用来删除数据DELETE FROM orders WHERE order_id 20250101001;这里必须多说一句UPDATE 和 DELETE 都有一个共同点WHERE 条件一定要写清楚一定要谨慎。如果漏掉 WHERE 条件或者条件写错了执行的结果就是整张表的数据全被改掉或删掉。这不是开玩笑我身边至少有三个人犯过这个错其中一个是上线前清理测试数据本来想删某一天的数据结果 WHERE 条件判断写反了把正式数据全删了最后从备份里恢复折腾了一整晚。所以我的习惯是执行 UPDATE 和 DELETE 之前先把同样的 WHERE 条件放进 SELECT 里跑一遍看看选中的是不是我真正想改的目标。这个习惯救了我不止一次。3. 进阶玩法SQL 真正厉害的地方3.1 多表关联JOIN 的核心思维单表查询只是入门SQL 真正的威力在于把多张表关联起来。现实业务中的表设计通常都是分散的用户信息存一张表订单信息存一张表商品信息存一张表。你想知道“哪些用户买了哪些商品”就必须把表和表通过关键字段串联起来这个操作就是 JOIN。看一个最常见的例子。想查每一笔订单对应的用户昵称订单表 orders 里只有 user_id没有用户昵称昵称在 users 表里那就这样写SELECT t1.order_id, t2.nickname, t1.amount FROM orders t1 LEFT JOIN users t2 ON t1.user_id t2.user_id;这里我给表起了别名 t1、t2省去重复打表全名的麻烦。LEFT JOIN 的意思是以 orders 表为主每一笔订单都会保留下来如果 users 表里找不到对应的用户昵称字段就显示为 NULL。JOIN 的思维方式简单说就是“找共同点”。表 A 和表 B 之间的 JOIN 条件就是它们之间共有的那个字段。写复杂查询的时候我习惯先在草稿纸上画出表之间的关系哪张表是主表、哪张表是附带的、谁和谁通过什么字段关联。画清楚了再写 SQL效率会提高很多。记得有一次帮业务部门取数要分析“买了 A 类商品的人还买了什么”涉及的关联表有五张。我一开始直接上手写 SQL写完发现结果明显不对订单数疯涨了好几倍。后来耐着性子画表关系图才发现其中两张表是多对多关系关联的时候中间少了张关联表导致每一笔主订单被放大成了多行。这就是 JOIN 没搞清楚“关系基数”惹的祸。3.2 窗口函数一行代码搞定排名和累计如果你关注过相关热词应该注意到“SQL 窗口函数”这两年特别火。窗口函数可以说是 SQL 进阶的一道分水岭也是很多面试官喜欢问的点。窗口函数解决的核心问题是“在每一行数据上同时看到整组数据的计算结果”。比如你想给每个用户的订单按金额从高到低排名传统写法要用自连接或者复杂的子查询效率低、代码又长。用窗口函数就简单多了SELECT user_id, order_id, amount, RANK() OVER (PARTITION BY user_id ORDER BY amount DESC) AS user_rank FROM orders;PARTITION BY user_id 的意思是“按用户分组”ORDER BY amount DESC 的意思是“组内按金额从高到低排”RANK() 则给每一行生成名次。这样查出来的结果里每个用户的第一大单、第二大单都清清楚楚。除了排名窗口函数还能做累计求和、移动平均、同比环比等分析。比如想看每个用户历史累计下单金额可以这样写SELECT user_id, order_id, amount, SUM(amount) OVER (PARTITION BY user_id ORDER BY create_time) AS cumulative_amount FROM orders;这条语句的计算逻辑是按用户分组组内按时间排序然后逐行累加金额每多一笔订单cumulative_amount 就更新一次。这种“逐行看累积”的能力是普通 GROUP BY 很难直接实现的。我个人的体会是窗口函数学起来有点绕但一旦掌握很多之前要写好长一段逻辑的查询都能浓缩成一行。它特别适合做用户行为留存分析比如统计每个用户在注册后第几天完成了首次购买这类分析在地推或运营活动评估里非常常见。3.3 慢 SQL 优化EXPLAIN 主要看哪些信息大数据量的系统跑久了你一定会遇到“这个报表怎么查了五分钟还没出来”的情况这就是慢 SQL。这时候最常用、也是最直接的诊断工具就是 EXPLAIN用来查看数据库执行这条 SQL 时的执行计划。对新手来说EXPLAIN 输出的信息里优先关注这几列就够了type反映访问类型。从好到差依次是 system const eq_ref ref range index ALL。如果看到 ALL意味着全表扫描这是最差的情况通常说明查询没有走索引。key实际使用的索引名称。如果这列是 NULL说明没有使用任何索引。rows预估需要扫描的行数。这个数字越小越好如果它非常大说明查询的成本很高。Extra一些额外信息如果出现 Using filesort文件排序或 Using temporary使用临时表通常也意味着查询存在优化空间。举个例子一个几百万行的订单表按 user_id 查询订单如果 user_id 字段没有建索引EXPLAIN 里 type 就会显示 ALLrows 可能显示几百万。这时候只要在 user_id 上加个索引同样的查询可能从秒级降到毫秒级。关于慢 SQL 优化我有一条比较实用的经验优化之前先搞清楚瓶颈到底在哪。是缺索引、查询条件写得太宽泛、还是 JOIN 的表实在太多不要拿着一套模板往所有查询上套。比如有些新手一看到查询慢就加索引但如果慢在 ORDER BY 排序上排序字段没有合适的索引设计加多少单列索引都不一定有效。4. SQL 的实际应用场景与行业价值4.1 数据分析师的一天取数、报表、专项分析如果你从事数据分析或商业分析相关工作SQL 大概率是你每天打开电脑后接触的第一个工具。早晨上班第一件事可能就是打开工单系统看业务方提来的取数需求——“帮我看一下最近 30 天各渠道的注册用户数、次日留存率和人均付费金额”。这个需求拆解开来就是三张临时表加一个 JOIN 的关系中间可能还要套子查询、用聚合函数最后用 GROUP BY 汇成一张结果表。我认识一个运营转行的数据分析师入职后白天用 SQL 取数晚上刷 SQL 面试题一边应付工作一边啃知识点。他跟我说真正让他 SQL 水平突飞猛进的不是刷题而是频繁地“被业务方追问”。每次把结果交上去业务方都会问“为什么这个渠道的留存率比上周低了”“能不能把人均付费金额按新老用户拆开看看”。这些问题不断驱动他加深 SQL 的用法CASE WHEN 做条件判断、DATE_DIFF 算时间差、窗口函数算留存、子查询做临时结果集。SQL 最大的价值就在这里它能让你从被动等数据变成主动思考数据里的人。4.2 后端开发与业务系统CRUD 只是及格线对后端开发工程师来说SQL 更是吃饭的家伙。业务系统的每个操作背后几乎都是 SQL 在驱动用户注册时要往 users 表插入记录用户登录时要查用户的密码哈希商品列表页要分页查询商品信息下单要同时往订单表、订单明细表、库存表等多个表里写数据还要保证这些操作要么全部成功、要么全部失败这就涉及事务概念。这里我想多说一句很多后端新人在写 SQL 时只求能跑通不太关心性能和边界情况。但系统一上线、数据量一上来问题就全暴露了。比如分页查询用的是 LIMIT 100000, 20越到后面页数越慢因为数据库要把前 10 万行都扫描一遍再跳过比如循环里一条一条执行 INSERT几百条数据要插大半天再比如没有对高频查询字段建索引导致前台接口响应越来越慢。这些问题其实从一开始写 SQL 的时候就可以通过规范化习惯来避免。4.3 数据库运维与安全别忽略数据库管理这件事再往外一圈数据库管理员DBA和数据运维人员的工作更是建立在 SQL 之上的。别人负责用 SQL 取数他们负责保证数据不丢、不慢、不泄露。热词里很多人搜的都是“SQL Server 2008 R2 下载”“SQL Server 2019 安装教程”说明不少新手在环境准备阶段就会遇到问题。SQL Server 等商业数据库的安装历来不省心最常见的坑包括安装到一半提示“无法卸载 SQL Server 2008 R2 安装程序支持文件因为安装了其他组件”、提示“无法启动 Windows Management Instrumentation (WMI) 服务”、或者安装后死活连不上本地实例。这些问题大多是环境依赖和权限问题解决的方法也因人而异但我可以分享一个底层原则安装之前先把系统防火墙、Windows 更新、旧版 SQL Server 残留组件都清理干净然后用管理员身份运行安装程序很多报错都能提前避开。安全方面SQL 注入是绕不开的话题。凡是接入了互联网的应用系统如果 SQL 语句是拿用户输入直接拼出来的就很有可能被人利用输入框注入恶意代码轻则绕过登录验证重则拖走整库数据。数据库的权限控制也同样重要线上数据库的主账号绝对不应该直接暴露给业务应用应用应该用只读账号或按需授权的账号这样即使应用被黑攻击者拿到的权限也有限。5. 新手入坑指南选型、安装、工具与学习路线5.1 数据库怎么选、装哪个版本很多新手面临的第一个选择困难症是我到底该学 MySQL 还是 SQL Server 还是 Oracle我的建议很直接如果没有特殊的工作或课程要求优先学 MySQL。原因有三第一它完全免费、社区活跃遇到问题搜一下基本都有答案第二它在互联网行业的使用率极高很多中小公司的核心业务都在 MySQL 上第三它安装相对简单对电脑配置要求也不高适合个人折腾。当然如果你所在的公司用的是 SQL Server 或 Oracle那就跟着公司技术栈走。SQL Server 在 Windows 环境下的图形化管理工具非常成熟做入门学习也很友好。网上搜索量很大的“SQL Server 2019 安装”“SQL Server 2022 下载”基本都是围绕版本选择和安装环境来提问的。这里我提醒一句2022 版本功能更先进但如果你的电脑配置比较旧装 2019 其实也完全够用不必一味追新。5.2 可视化工具怎么挑写 SQL 不能光靠黑色的命令行窗口一个好用的可视化工具能帮你大幅提升效率。我常用的组合是MySQL优先推荐 DBeaver免费开源、跨平台还能连各种数据库。Navicat 也很好用界面更精致但商业版收费。SQL Server直接使用微软官方自带的 SQL Server Management StudioSSMS功能和体验都很完整。Oracle很多老项目用 PL/SQL Developer。如果你要连接局域网内另一台机器上的 Oracle 数据库除了配置好网络还要注意 Oracle 客户端版本和服务器版本要匹配否则极容易报连接错误——这正好也是热词里很多人查的问题。千万不要同时开太多工具每换一个工具就要重新学习一遍快捷键和界面成本其实很高。选一个用熟比“全都装来看看”更实际。5.3 学习路线和资源怎么学才不迷路SQL 是一门上手容易、深入很难的语言。我的建议是沿着“基础语法 → 单表查询 → 多表查询 → 聚合统计 → 窗口函数 → 查询优化”这条线循序渐进每一步都配上真实场景练习。如果你喜欢看书《SQL 必知必会》是一本评价很高的小册子大概两天就能翻完适合扫盲。《SQL 经典实例》适合当工具书遇到问题随手翻类型场景。如果你更喜欢动手可以去刷在线题很多 OJ 平台都有 SQL 题库从易到难都有对巩固 JOIN、子查询和窗口函数特别有效。学习的过程中一定要多写多练而不是只看不练。SQL 和骑自行车很像你看再多攻略不亲自蹬几圈永远都学不会。遇到不会的写法先自己想再查资料最后再看别人的解法这样记忆才深刻。我在带新人的时候也发现那些进步快的同事往往都有一个共同特征愿意为一个查询尝试好几种不同的写法并思考它们之间在逻辑和性能上的差异。这种习惯比多背几条语法有用得多。6. 经验补充几个容易踩的坑6.1 NULL 真不是 0接触 SQL 时间长了你会发现 NULL 是一个极其特殊的存在。它不代表 0也不代表空字符串而是代表“这个值是未知的”。在 WHERE 条件里字段 NULL永远查不出东西来你必须写成字段 IS NULL才行。在聚合函数里COUNT(字段) 会忽略 NULL 值但 COUNT(*) 不会。在计算金额求平均值的时候AVG 也会忽略 NULL 行这意味着如果某些数据缺失且没处理统计结果可能和你脑海里的预期差很多。有一个我做数据分析时踩过的坑统计用户平均下单金额订单表里有几笔退款订单金额是 NULL我的 SQL 用的是AVG(amount)结果算出来的均值比真实情况高了一点。排查时发现 AVG 自动忽略了 NULL 那些行而业务上这些退款订单应该记成 0 才对。所以处理数据前先想清楚哪些字段可能为 NULL业务上应该怎么定义这些 NULL这种提前规划的习惯能帮你避免无数个“看起来数字怪怪的”问题。6.2 DELETE 还是 TRUNCATE清空一张表的数据有人用 DELETE FROM 表名有人用 TRUNCATE TABLE 表名。两者的区别是DELETE 是一行一行删可以通过事务回滚找回TRUNCATE 是直接把整张表的存储空间清空速度极快但不可回滚。如果只是想清空临时表的数据用于重跑流程TRUNCATE 更高效如果只是删掉部分数据必须用 DELETE 加 WHERE 条件。另外一个容易被忽略的点是TRUNCATE 之后很多数据库会把自增主键的计数重置而 DELETE 不会。这在导入导出数据的时候很容易踩坑我之前就遇到过用 DELETE 清空表后重新插入数据主键竟然接着之前的数继续往下走导致和另一个系统对接时 ID 对不上。6.3 写 SQL 的通用习惯建议最后分享几个我写 SQL 时坚持的习惯希望能帮你少踩坑每条查询语句都写好缩进。一个 SELECT 套三个 JOIN 再加两个子查询的长语句如果没有缩进过两周连你自己都读不下去。表名和字段名尽量写清楚不要贪图少打几个字就用缩写。SELECT a.nickname, b.amount FROM u a JOIN o b ON a.id b.uid这种语句自己看都费劲更别说别人 review。执行 UPDATE 和 DELETE 前先用相同 WHERE 条件的 SELECT 确认目标数据。这个习惯救过我至少三次。对耗时较长的查询尽量在低谷期执行而且提前和同事打好招呼别一个人默默跑一个拖垮全局的大查询。SQL 说到底是和数据对话的工具写出来的语句不只是给数据库看的也是给未来的自己和同事看的。把代码写清楚、写稳妥比炫技高级得多。我个人在实际操作中的体会是SQL 最大的魅力在于它的确定性和即时反馈给你一张表、一个问题你写一条语句数据库立刻就能告诉你答案。这种正反馈特别适合建立信心。学 SQL 的路上没有太多玄学多写、多查、多总结你的数据处理能力一定会肉眼可见地增长。
返回列表