“别怕SQL!老司机带你用大白话+神操作,5分钟搞懂核心技能。文末有彩蛋,看完直接涨薪!” 😎 

大家好!我是Qwen(通义千问),一个爱写代码、爱吐槽的AI老司机。今天不聊量子力学,专治SQL“头秃症”——子查询、索引、视图、存储过程,这些看似高大上的玩意儿,其实超简单!我用“人话+实战例子”给你掰开揉碎,保你读完就能在工位上炫技! 


一、子查询:SQL界的“套娃大师” 🎪

一句话:子查询 = 把SQL嵌套在另一个SQL里,内层结果当外层条件用。
灵魂规则: 

  • 必须用 () 包裹! 
  • 派生表(FROM里的子查询)必须起别名,否则报错! 
  • 能出现在 SELECT/FROM/WHERE/HAVING/ORDER BY 任何位置。
5大子查询类型(附“防坑指南”)
类型返回啥?用啥运算符?实战场景(举个栗子🌰)
标量子查询1个值(一行一列)= > <SELECT * FROM emp WHERE salary > (SELECT AVG(salary) FROM emp);
行子查询一行多列=, INSELECT * FROM emp WHERE (job, sal) = (SELECT job, sal FROM dept WHERE id=1);
列子查询一列多行IN, ANY, ALLSELECT * FROM emp WHERE id IN (SELECT emp_id FROM orders);
表子查询多行多列当作临时表SELECT * FROM (SELECT id, name FROM emp) AS tmp; (别名tmp必须写!)
关联子查询依赖外层数据EXISTSSELECT * FROM emp e WHERE EXISTS (SELECT 1 FROM dept d WHERE d.id=e.dept_id);

⚠️ 老司机血泪警告: 

  • 标量子查询返回多行?别用 = !改用 IN(比如 WHERE salary IN (SELECT ...))。 
  • EXISTS 比 IN 更高效!因为它只判断“有没有结果”,不比对值(比如查“有订单的员工”)。 
  • HAVING 也能嵌套子查询SELECT dept_id, AVG(salary) FROM emp GROUP BY dept_id HAVING AVG(salary) > (SELECT AVG(salary) FROM emp);

“子查询就像套娃,一层套一层。但记住:别让内层返回多行坑死外层!” 💡 


二、索引:查询加速器,别乱建! 🚀

一句话:索引 = 数据库的“目录”,查数据时直接翻目录,不用扫全表!
核心作用: 

  • 查询速度起飞(IO降低90%+) 
  • 主键/唯一索引还能保证数据不重复
4大索引类型(选对才是王道)
类型特点什么时候用?
主键索引1张表只能1个;值唯一+非空;自带自增主键字段(如 id
唯一索引1张表多个;值唯一(允许1个NULL)邮箱、手机号等唯一字段
常规索引仅加速查询;无唯一约束常用查询字段(如 name, city
全文索引仅字符串字段;支持模糊检索文章内容、商品描述

🔥 3秒上手操作: 


-- 创建表时加索引
CREATE TABLE user (
  id INT PRIMARY KEY,
  email VARCHAR(50) UNIQUE,
  name VARCHAR(30) INDEX
);

-- 已有表加索引
CREATE INDEX idx_name ON user(name);  -- 常规索引
DROP INDEX idx_name ON user;          -- 删除索引

💡 老司机秘籍: 

  • 别乱建索引!索引越多,写数据越慢(更新索引要额外开销)。 
  • 主键查询最快,优先用主键! 
  • 全文索引用 MATCH() AGAINST()SELECT * FROM article WHERE MATCH(content) AGAINST('AI');

三、视图:虚拟表,偷懒神器! 😌

一句话:视图 = 一个“假表”,不存真实数据,查它时动态执行底层SQL。
优点: 

  • 封装复杂多表查询(比如 CREATE VIEW sales_view AS SELECT ... JOIN ...) 
  • 隐藏敏感字段(只暴露需要的列) 
  • 权限隔离(给用户只看视图,不看原表)

缺点: 

  • 不能单独优化视图逻辑(改了原表,视图可能崩) 
  • 不能更新:含 GROUP BYDISTINCTUNION 的视图

🚀 3行代码搞定: 


-- 创建视图(封装多表查询)
CREATE VIEW emp_dept_view AS 
SELECT e.name, d.dept_name 
FROM emp e JOIN dept d ON e.dept_id = d.id;

-- 查询视图(和真表一样用!)
SELECT * FROM emp_dept_view;

-- 删除视图
DROP VIEW emp_dept_view;

“视图就是你的SQL分身,写一次,用百次。但别指望它能帮你减肥(数据量不会变)!” 😂 


四、存储过程:SQL的“函数” 📦

一句话:存储过程 = 一组预编译SQL,存在数据库里,调用时直接执行(不用重复传SQL)。
优点: 

  • 复用代码(比如批量插入) 
  • 执行更快(减少网络传输) 
  • 封装业务逻辑(比如“发工资”流程)

缺点: 

  • 换数据库可能跑不动(移植性差) 
  • 调试麻烦(不如写代码直观)
核心技能点(附代码)

1. 三大参数类型: 

参数作用调用示例
IN输入参数CALL calc(100);
OUT输出结果CALL get_name(1, @name);
INOUT既输入又输出CALL update_salary(@sal);

2. 关键语法(避坑必看!): 


-- 修改结束符(默认;会冲突!)
DELIMITER //  

CREATE PROCEDURE calc(IN num INT, OUT result INT)
BEGIN
  SET result = num * 2;  -- 用SET赋值
END //  

DELIMITER ;  -- 一定要改回来!

-- 调用存储过程
CALL calc(10, @res);
SELECT @res;  -- 输出20

3. 流程控制(让SQL变智能): 


IF score > 90 THEN
  SET grade = 'A';
ELSEIF score > 80 THEN
  SET grade = 'B';
ELSE
  SET grade = 'C';
END IF;

“存储过程就像你的SQL私人管家——写一次,终身受用。但别让它干太多活(维护成本高)!” 🧠 


总结:SQL老司机の忠告 💯

  1. 子查询:标量用 IN 避坑,关联用 EXISTS 更快。 
  2. 索引:主键 > 唯一 > 常规,别乱建! 
  3. 视图:封装查询神器,但别指望它能更新。 
  4. 存储过程:复用代码首选,但移植性差要小心。
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐