当前位置: 首页 > news >正文

数据库学习记录

📦 第03章 基本的SELECT语句:数据世界的「望远镜」


🎯 SQL家族三大门派

/* 
🔧 DDL(数据建筑师): 
   CREATE 建房子 | ALTER 装修 | DROP 拆房子 
   RENAME 改门牌号 | TRUNCATE 清空仓库

✏️ DML(数据搬运工): 
   INSERT 进货 | DELETE 扔垃圾 | UPDATE 调库存 
   SELECT 查账本(本章主角!)

🔐 DCL(数据保安): 
   COMMIT 锁保险柜 | ROLLBACK 时光倒流 
   SAVEPOINT 存档点 | GRANT 发门禁卡 | REVOKE 收卡
*/

🔭 基础SELECT三连击

1. 数据望远镜初体验

-- 看伪表DUAL的虚拟舞台表演
SELECT 1+1, 3*2 FROM DUAL;  -- 输出:2 | 6

-- 掏出员工表全家福
SELECT * FROM employees;

-- 精准观察三列数据
SELECT employee_id, last_name, salary FROM employees;

2. 列の「艺名」设置指南

-- 给列起外号的三种姿势
SELECT 
  employee_id AS 工号,          -- 标准艺名
  last_name "神秘代号",         -- 带空格的艺名要加引号
  department_id 部门ID          -- 最简写法(小心关键字!)
FROM employees;

3. 数据去重神器

-- 普通青年查部门:107条重复数据
SELECT department_id FROM employees;

-- 极客青年查部门:12个不重复ID
SELECT DISTINCT department_id FROM employees; -- DISTINCT去重buff

⚠️ 空值(Null)生存指南

空值运算的坑

-- 错误示范:年终奖可能为null的员工
SELECT 
  employee_id,
  salary * (1 + commission_pct) * 12 "年工资" -- null会导致结果变null!
FROM employees;

-- 正确姿势:给null上保险
SELECT 
  employee_id,
  salary * (1 + IFNULL(commission_pct, 0)) * 12 "年工资" -- 用IFNULL兜底
FROM employees;

🛡️ 特殊符号生存技巧

防冲突护甲(着重号)

-- 当表名撞名SQL关键字时
SELECT * FROM `order`;  -- 用反引号包裹危险表名

数据表「体检报告」

-- 查看employees表的结构说明书
DESCRIBE employees;   -- 全写版
DESC employees;       -- 极简版(同样有效!)

🔍 数据过滤器WHERE

精准定位90号部门

-- 查找部门90的同事
SELECT * 
FROM employees
WHERE department_id = 90;  -- 等号过滤

-- 寻找叫King的大佬(MySQL不区分大小写!)
SELECT *
FROM employees
WHERE last_name = 'King'; -- Oracle严格区分,MySQL很随意

💡 冷知识加油站

  1. 伪表DUAL
    虚拟舞台,专门用于不需要真实表的计算表演

  2. 常数查询

    SELECT '我是常数', employee_id FROM employees; -- 每行都带这个常数
    
  3. MySQL大小写哲学

    • 表名/列名 区分大小写(Linux系统)
    • 字符串内容 不区分大小写('King’和’king’等价)
  4. DESC双面人生
    既是「降序排序」的关键词,也是「查看表结构」的命令!


总结:SELECT就像数据世界的望远镜,掌握这些技巧让你想看哪里点哪里!🎯


📊 第04章 运算符:数据世界的「魔法公式」


🧙♂️ 算术符的奇妙世界:+ - * / DIV % MOD

基础算术表演

-- 数字与字符串的暧昧(隐式转换)
SELECT 100 + '1' AS 暧昧相加,  -- 101('1'被温柔地转为数字)
       100 + 'a' AS 乱码相加  -- 100('a'被当作舔狗0处理)
FROM DUAL;

-- NULL的隐身术:任何运算遇到NULL都会消失!
SELECT 100 + NULL AS 消失的结果  -- NULL(像被施了隐身咒)
FROM DUAL;

实战:寻找双号员工

SELECT employee_id, last_name, salary 
FROM employees
WHERE employee_id % 2 = 0;  -- % 是取余神器

🔍 比较符侦探社:= <=> != < > …

字符串破案指南

-- 当数字遇见字符串(大型隐式转换现场)
SELECT 1 = '1' AS 穿越相爱,    -- 1(true)
       1 = 'a' AS 单相思,     -- 0(false)
       0 = 'a' AS 舔狗の爱    -- 1(true)
FROM DUAL;

NULL侦探事务所

-- 普通等于遇到NULL就懵逼
SELECT 1 = NULL AS 迷茫结果,   -- NULL(未知)
       NULL = NULL AS 量子纠缠 -- NULL(仍是未知)
FROM DUAL;

-- 安全等于<=>:唯一能看透NULL的X光眼
SELECT last_name, salary
FROM employees
WHERE commission_pct <=> NULL;  -- 精准捕捉NULL值

🕵️♂️ 特殊搜查技巧包

IS NULL侦探

-- 查找没有提成的打工人
SELECT last_name, salary 
FROM employees
WHERE commission_pct IS NULL;  -- ISNULL(commission_pct) 也可

IN/ NOT IN 多选神器

-- 部门10/20/30的同事集合!
SELECT last_name, department_id
FROM employees
WHERE department_id IN (10, 20, 30);

-- 拒绝6K/7K/8K工资的叛逆选择
SELECT last_name, salary
FROM employees 
WHERE salary NOT IN (6000, 7000, 8000);

🔮 通配符魔法:LIKE的咒语书

% 魔法:任意长度替身

-- 名字里藏着小a的巫师
SELECT last_name 
FROM employees
WHERE last_name LIKE '%a%';  -- 像*通配符一样强大

-- a开头名字的预言(魔杖一挥)
SELECT last_name
FROM employees
WHERE last_name LIKE 'a%';   -- 首字母检测术

_ 魔法:精准定位符

-- 第二个字符是a的密语
SELECT last_name
FROM employees
WHERE last_name LIKE '_a%';  -- _代表一个任意字符

-- 查找_和a的羁绊(需要转义符\)
SELECT last_name
FROM employees
WHERE last_name LIKE '_\_a%'; -- 用\解除_的魔法效果

❄️ 冷知识暴风雪

  1. DIV 与 /

    • DIV 是整数除法(5 DIV 2 = 2)
    • / 是精确除法(5/2 = 2.5)
  2. MOD 的替身
    %MOD 是双胞胎,8 MOD 3 = 2,8 % 3 = 2

  3. LIKE 的隐藏Boss

    -- 同时包含a和e的名字(两种写法)
    WHERE last_name LIKE '%a%' AND last_name LIKE '%e%';
    WHERE last_name LIKE '%a%e%' OR last_name LIKE '%e%a%';
    
  4. 安全等于的真相
    <=> 可以处理NULL比较,但会降低SQL性能,非必要不滥用


口诀记忆
“算术比较加LIKE,NULL处理要勤快;
IN把多个条件带,通配符里藏精彩!” 🪄


📚 第05章 排序与分页:数据の排队术与翻页魔法


🎩 排序:给数据队伍喊口令!

1. 基础排队法(ORDER BY)

-- 默认按工资从低到高排队(偷偷用了ASC)
SELECT employee_id, last_name, salary
FROM employees
ORDER BY salary; -- 像军训教官的默认口令:"向前看齐!"

-- 明确喊出口令:工资从高到低排队!
SELECT employee_id, last_name, salary
FROM employees
ORDER BY salary DESC; -- DESC是"向后转!"

2. 别名の妙用(WHERE看了会流泪)

-- 用annual_sal别名排序(WHERE中不能用别名!)
SELECT employee_id, salary, salary*12 annual_sal
FROM employees
ORDER BY annual_sal; -- 给年薪起外号后排序

3. 排序优先级法则

-- 先按部门倒序排,同部门按工资升序排
SELECT employee_id, department_id, salary
FROM employees
ORDER BY department_id DESC, salary ASC; -- 像先按班级排,再按身高排

⚠️ 重要顺序口诀
FROM → WHERE → ORDER BY → LIMIT
(查表→过滤→排队→截取)


📖 分页:数据界的「自动翻书术」

1. LIMIT基础公式

-- 第1页:前20条(从0号位开始)
SELECT employee_id, last_name
FROM employees
LIMIT 0, 20; -- 悄悄数数:0,1,2...19

-- 第2页:接着20条(数学课代表上线)
SELECT employee_id, last_name
FROM employees
LIMIT 20, 20; -- (2-1)*20=20

万能分页公式
LIMIT (页码-1)*每页条数, 每页条数

2. 花式分页技巧

-- 高薪Top10榜单
SELECT employee_id, last_name, salary
FROM employees
WHERE salary > 6000
ORDER BY salary DESC
LIMIT 10; -- LIMIT 0,10 的简写

-- 精准翻到第32条(想直接看某条数据?)
SELECT employee_id, last_name
FROM employees
LIMIT 31, 1; -- 位置偏移从0开始计数!

3. MySQL8.0 新姿势:OFFSET

-- 新语法更符合人类直觉
SELECT employee_id, last_name
FROM employees
LIMIT 2 OFFSET 31; -- 先跳过31条,再取2条

❄️ 冷知识暴风雪

  1. 隐式排序陷阱
    不加ORDER BY时"按添加顺序显示"只是假象!数据物理存储顺序可能变化,必须显式排序才能保证顺序稳定

  2. 别名禁用区
    WHERE中不能使用SELECT列的别名(因为执行顺序WHERE在SELECT之前!)

  3. LIMIT性能玄学
    深分页(如LIMIT 100000,20)会变慢,推荐使用WHERE id > 上页最大ID 优化

  4. OFFSET的逆袭
    MySQL8.0的LIMIT ... OFFSET更易读,但和老语法LIMIT 偏移量,数量完全等价


口诀记忆
“排序口令ORDER BY,DESC倒序ASC上;
LIMIT分页数学强,新语法OFFSET更香!” 🪄


📊 第06章 多表查询:数据表的「联谊派对」


🚨 笛卡尔积:大型数据相亲翻车现场

错误示范:全员乱组CP

-- 107个员工 × 27个部门 = 2889对无效CP!
SELECT employee_id, department_name 
FROM employees, departments;  -- 忘记牵红线(连接条件)

症状:每个员工和每个部门强行配对,数据爆炸!
治疗药方:添加WHERE连接条件,给数据牵红线❤️


💡 正确联谊姿势:数据CP配对指南

等值连接:门当户对的爱情

-- 用部门ID牵线成功
SELECT emp.employee_id, dept.department_name
FROM employees emp, departments dept
WHERE emp.department_id = dept.department_id; 

联谊小贴士

  • 多表同名字段必须带前缀(如emp.department_id
  • 表别名是派对的VIP铭牌(employees emp
  • N个表联谊至少需要N-1个连接条件!

🌈 多表CPの花式配对法

1. 自连接:我领导我自己

-- 查员工和他们的上司(都是同一张表!)
SELECT 打工人.employee_id AS "小弟ID", 
       上司.last_name AS "老大名字"
FROM employees 打工人, employees 上司
WHERE 打工人.manager_id = 上司.employee_id;

2. 非等值连接:工资段位匹配

-- 看看工资在哪个等级区间
SELECT e.last_name, e.salary, 
       j.grade_level AS "财富段位"
FROM employees e, job_grades j
WHERE e.salary BETWEEN j.lowest_sal AND j.highest_sal;

3. 三表联查:部门地址追踪

-- 员工+部门+地址三表联动
SELECT e.employee_id, d.department_name, l.city
FROM employees e, departments d, locations l
WHERE e.department_id = d.department_id
  AND d.location_id = l.location_id;

🔄 内外连接:包容性大不同

内连接:只展示成功CP

-- 只显示有部门的员工(SQL92写法)
SELECT e.last_name, d.department_name
FROM employees e, departments d
WHERE e.department_id = d.department_id;

-- SQL99更优雅的写法
SELECT e.last_name, d.department_name
FROM employees e
INNER JOIN departments d  -- INNER可省略
ON e.department_id = d.department_id;

外连接:给单身狗留位置

-- 左外连接:所有员工都要显示(即使没部门)
SELECT e.last_name, d.department_name
FROM employees e
LEFT JOIN departments d  -- 左表是宇宙中心
ON e.department_id = d.department_id;

-- 右外连接:所有部门都要显示(即使没员工)
SELECT e.last_name, d.department_name
FROM employees e
RIGHT JOIN departments d  -- 右表是主角
ON e.department_id = d.department_id;

⚡ SQL92 vs SQL99 语法Battle

SQL92的局限

-- MySQL不支持这种外连接写法(Oracle可以)
SELECT e.last_name, d.department_name
FROM employees e, departments d
WHERE e.department_id(+) = d.department_id;  -- ❌

SQL99的优势

-- 清晰的JOIN...ON结构(MySQL推荐)
SELECT e.last_name, d.department_name
FROM employees e
LEFT OUTER JOIN departments d  -- OUTER可省略
ON e.department_id = d.department_id
JOIN locations l  -- 轻松连接第三张表
ON d.location_id = l.location_id;

🧩 满外连接:UNION来救场

UNION vs UNION ALL

-- 左外 + 右外 - 去重 = 满外(MySQL没有FULL JOIN)
(SELECT e.last_name FROM employees e LEFT JOIN departments d ...)
UNION
(SELECT e.last_name FROM employees e RIGHT JOIN departments d ...);

-- 高性能版(不去重)
(SELECT ...) UNION ALL (SELECT ...);

冷知识

  • UNION 去重但效率低
  • UNION ALL 保留所有结果,效率更高!

💣 避坑指南 & 冷知识

  1. 多表查询顺序
    FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT

  2. 别名禁区
    表别名一旦声明,SELECT和WHERE中必须使用别名

  3. NULL的暧昧
    多表连接时,NULL值不会自动匹配,需用外连接显示

  4. 满外连接替代方案
    通过LEFT JOIN + RIGHT JOIN + UNION组合实现


口诀记忆
“多表连接要红线,别名前缀防混乱;
内连只要成功配,外连照顾单身汉!” 🎯

知识地图

多表查询
等值连接
非等值连接
自连接
内连接
外连接
左外连接
右外连接
结果处理
排序ORDER BY
分页LIMIT
单字段排序
多字段排序
传统写法
OFFSET新写法

🌟 SQL99标准连接详解:用JOIN…ON玩转多表关系


📌 内连接(INNER JOIN) —— 只匹配成功的CP

核心特点

  • 精准匹配:仅返回两个表中完全匹配的行
  • 隐式过滤:自动过滤掉无匹配项的数据
  • 性能优势:通常执行效率较高

语法示例

-- 查询有部门的员工信息(显式写法)
SELECT e.last_name, d.department_name
FROM employees e
INNER JOIN departments d  -- INNER可省略
ON e.department_id = d.department_id;

-- 多表内连接(部门+地址)
SELECT e.employee_id, l.city
FROM employees e
JOIN departments d ON e.department_id = d.department_id
JOIN locations l ON d.location_id = l.location_id;

适用场景

  • 需要精确匹配的关联数据查询
  • 当确定关联字段不存在NULL值时

🚪 左外连接(LEFT OUTER JOIN) —— 左表是宇宙中心

核心特点

  • 左表特权:保留左表所有行,右表无匹配则显示NULL
  • 数据完整性:确保左表数据不丢失
  • OUTER可省略LEFT JOIN 等价于 LEFT OUTER JOIN

语法示例

-- 查询所有员工(包括无部门人员)
SELECT e.last_name, d.department_name
FROM employees e
LEFT JOIN departments d 
ON e.department_id = d.department_id;

-- 左外连接三表(员工+部门+地址)
SELECT e.employee_id, l.city
FROM employees e
LEFT JOIN departments d ON e.department_id = d.department_id
LEFT JOIN locations l ON d.location_id = l.location_id;

适用场景

  • 需要保留主表全部数据(如员工表为主)
  • 分析存在空值的数据分布(如统计未分配部门员工)

🚪 右外连接(RIGHT OUTER JOIN) —— 右表是绝对主角

核心特点

  • 右表特权:保留右表所有行,左表无匹配则显示NULL
  • 数据透视:常用于维度表分析
  • OUTER可省略RIGHT JOIN 等价于 RIGHT OUTER JOIN

语法示例

-- 查询所有部门(包括无员工的部门)
SELECT d.department_name, e.last_name
FROM employees e
RIGHT JOIN departments d
ON e.department_id = d.department_id;

-- 右外连接三表(反向关联)
SELECT d.department_name, l.city
FROM employees e
RIGHT JOIN departments d ON e.department_id = d.department_id
RIGHT JOIN locations l ON d.location_id = l.location_id;

适用场景

  • 需要保留维度表全部数据(如展示所有部门)
  • 检查未被使用的数据(如查找从未被分配的部门)

🌌 满外连接(FULL OUTER JOIN) —— 数据全宇宙

核心特点

  • 数据全保留:返回左右表所有行,无匹配则对方字段为NULL
  • MySQL不支持:需通过UNION模拟实现
  • 性能注意:大数据量时谨慎使用

语法实现

-- 模拟满外连接(员工+部门)
(SELECT e.last_name, d.department_name
 FROM employees e LEFT JOIN departments d
 ON e.department_id = d.department_id)
UNION  -- 去重合并
(SELECT e.last_name, d.department_name
 FROM employees e RIGHT JOIN departments d
 ON e.department_id = d.department_id);

-- 高性能版(不去重)
(SELECT ...) UNION ALL (SELECT ...) WHERE ...;

适用场景

  • 需要完整数据全景分析
  • 数据差异对比(如对比两个表差异记录)

🎯 对比总结表

连接类型关键字保留数据范围MySQL支持典型场景
内连接INNER JOINJOIN仅匹配成功的行精准关联查询
左外连接LEFT [OUTER] JOIN左表全部 + 右表匹配行主表数据保全
右外连接RIGHT [OUTER] JOIN右表全部 + 左表匹配行维度表分析
满外连接FULL OUTER JOIN左右表全部行数据全景展示(需UNION模拟)

🔥 高阶技巧点拨

1. ON vs WHERE 的区别

-- ON 是连接条件(先过滤后连接)
SELECT e.last_name, d.department_name
FROM employees e
LEFT JOIN departments d 
ON e.department_id = d.department_id 
   AND d.department_name = 'IT'  -- 连接时过滤

-- WHERE 是最终过滤(先连接后过滤)
SELECT e.last_name, d.department_name
FROM employees e
LEFT JOIN departments d 
ON e.department_id = d.department_id
WHERE d.department_name = 'IT';  -- 连接后过滤

2. 自连接外连接

-- 查询员工及其领导(包括无领导的CEO)
SELECT 员工.last_name AS 员工, 
       领导.last_name AS 领导
FROM employees 员工
LEFT JOIN employees 领导
ON 员工.manager_id = 领导.employee_id;

3. 多表连接顺序优化

/* 推荐写法:主表在前,关联表按层级连接 */
SELECT e.last_name, l.city
FROM employees e
LEFT JOIN departments d ON e.department_id = d.department_id
LEFT JOIN locations l ON d.location_id = l.location_id;

黄金法则
“内连精准匹配快,左外右外保一方,满外UNION来实现,ON在前来WHERE后!” 🚀

相关文章:

  • RocketMQ如何保证全链路消息不丢失?
  • docker容器制作和上传
  • Maven插件学习(二)——测试插件maven-surefire-pluigin
  • Linux的一些常见指令
  • 如何查看window电脑的GPU信息
  • docker部署onlyoffice(windows版)
  • Android系统的安全问题 - Android的启动时验证
  • WebGPU 全面解析:下一代 Web 图形与计算 API 的崛起
  • Pytorch学习笔记(六)Learn the Basics - Automatic Differentiation
  • 常见邮件协议
  • 自然语言处理(14:处理时序数据的层的实现)
  • 数学-算法
  • java对象模型
  • Unity游戏开发如何优化移动端的延迟渲染管线?
  • 【NLP 43、文本生成任务】
  • 使用HTML5和CSS3实现3D旋转相册效果
  • LeetCode热题100精讲——Top4:移动零【双指针】
  • SpringBoot底层原理
  • AndroidStudio 下载
  • 大疆上云api直播功能如何实现
  • 太原商城网站建设/如何做网络销售平台
  • 建筑网站源码/百度竞价排名正确解释
  • 可以做网站的域名后缀/360搜索引擎入口
  • 建设网站需要多大域名空间/线上营销活动主要有哪些
  • 在香港做网站需要什么软件/一站式软文发布推广平台
  • 河南教育平台网站建设/小程序源码网