01-总结

目录

[一、SQL 分类(按功能)](#一、SQL 分类(按功能))

[二、SELECT 的执行顺序与典型示例](#二、SELECT 的执行顺序与典型示例)

[1. 执行顺序(逻辑顺序)](#1. 执行顺序(逻辑顺序))

[2. 示例一:销售统计](#2. 示例一:销售统计)

[三、SQLite 表结构:ALTER / 删除列的做法](#三、SQLite 表结构:ALTER / 删除列的做法)

[1. ALTER TABLE 能做什么(SQLite)](#1. ALTER TABLE 能做什么(SQLite))

[2. 在 SQLite 中如何删除一列?](#2. 在 SQLite 中如何删除一列?)

[四、INSERT 细节与 SQLite 特有语法](#四、INSERT 细节与 SQLite 特有语法)

[1. 推荐写法:显式列名](#1. 推荐写法:显式列名)

[2. SQLite:INSERT OR ...](#2. SQLite:INSERT OR ...)

[3. 面试常用说法](#3. 面试常用说法)

[五、DISTINCT 去重规则](#五、DISTINCT 去重规则)

[六、WHERE 条件与基础运算符](#六、WHERE 条件与基础运算符)

[1. WHERE:永远是"按行过滤"](#1. WHERE:永远是“按行过滤”)

[2. NULL 判断要点](#2. NULL 判断要点)

[3. LIKE 模糊匹配](#3. LIKE 模糊匹配)

[七、排序:ORDER BY](#七、排序:ORDER BY)

[八、分页:LIMIT / OFFSET(SQLite / MySQL)](#八、分页:LIMIT / OFFSET(SQLite / MySQL))

[九、聚合函数 & 分组:GROUP BY / HAVING](#九、聚合函数 & 分组:GROUP BY / HAVING)

[1. 聚合函数(对"一组行"算一个值)](#1. 聚合函数(对“一组行”算一个值))

[2. WHERE vs HAVING](#2. WHERE vs HAVING)

[3. 示例:统计每个年龄人数,只保留人数 > 5 的年龄段,并倒序](#3. 示例:统计每个年龄人数,只保留人数 > 5 的年龄段,并倒序)

十、多表查询:JOIN

[1. JOIN 的本质](#1. JOIN 的本质)

[2. INNER JOIN(内连接)](#2. INNER JOIN(内连接))

[3. LEFT JOIN(左外连接)](#3. LEFT JOIN(左外连接))

[4. JOIN vs 子查询(IN / EXISTS)](#4. JOIN vs 子查询(IN / EXISTS))

十一、视图(View)

[1. 视图的本质](#1. 视图的本质)

[2. 视图 vs 表](#2. 视图 vs 表)

[3. 视图的使用场景](#3. 视图的使用场景)


一、SQL 分类(按功能)

口诀:先建表,再改行,再来查,最后保。

  • DDL(Data Definition Language)数据定义语言

    • 作用:定义和修改结构(表、视图、索引等)

    • 示例:CREATEALTERDROP

    • 口诀:定义结构

  • DML(Data Manipulation Language)数据操作语言

    • 作用:操作行数据(增删改)

    • 示例:INSERTUPDATEDELETE

    • 口诀:操作行

  • DQL(Data Query Language)数据查询语言

    • 作用:查询数据(结果集)

    • 核心:SELECT

    • 口诀:查数据

  • TCL(Transaction Control Language)事务控制语言

    • 作用:控制事务的提交与回滚

    • 示例:BEGINCOMMITROLLBACK

    • 口诀:控制成或败


二、SELECT 的执行顺序与典型示例

1. 执行顺序(逻辑顺序)

FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY → LIMIT


2. 示例一:销售统计

复制代码
SELECT seller, SUM(amount) AS total
FROM sales
WHERE amount > 0
GROUP BY seller
HAVING SUM(amount) > 1000
ORDER BY total DESC;

理解:

  1. FROM sales

    sales 表取数据。

  2. WHERE amount > 0

    只保留金额大于 0 的订单。

  3. GROUP BY seller

    按销售人员 seller 分组。

  4. SUM(amount) AS total

    统计每个销售的总销售额,命名为 total

  5. HAVING SUM(amount) > 1000

    只保留总销售额大于 1000 的销售。

  6. ORDER BY total DESC

    按总销售额从大到小排序。


三、SQLite 表结构:ALTER / 删除列的做法

1. ALTER TABLE 能做什么(SQLite)

  • 添加列:

    复制代码
    ALTER TABLE user ADD COLUMN phone TEXT;
  • 重命名表:

    复制代码
    ALTER TABLE user RENAME TO user_new;

2. 在 SQLite 中如何删除一列?

标准套路:新建新表 + 迁移数据 + 删旧表 + 重命名

步骤:

  1. 创建不包含该列的新表(结构正确)

  2. INSERT INTO ... SELECT ... 把需要的列迁移过去

  3. DROP TABLE 删除旧表

  4. ALTER TABLE ... RENAME TO ... 把新表改回原表名


四、INSERT 细节与 SQLite 特有语法

1. 推荐写法:显式列名

不推荐:

复制代码
INSERT INTO user
VALUES (1, 'Alice', 20, 'alice@test.com', '2025-01-01 10:00:00');

推荐:

复制代码
INSERT INTO user (id, name, age, email, created_at)
VALUES (1, 'Alice', 20, 'alice@test.com', '2025-01-01 10:00:00');

2. SQLite:INSERT OR ...

  • OR IGNORE

    出问题就当没插(不报错,不插入)

    复制代码
    INSERT OR IGNORE INTO user (id, name) VALUES (1, 'Alice');
  • OR REPLACE

    出问题就删旧的,插新的(底层是 delete + insert)

    复制代码
    INSERT OR REPLACE INTO user (id, name) VALUES (1, 'Alice');

3. 面试常用说法

  • 幂等插入(存在就忽略)

    INSERT OR IGNORE

  • 存在则覆盖 / 不存在则插入

    INSERT OR REPLACE(本质是 delete + insert)


五、DISTINCT 去重规则

  • 单列:

    复制代码
    SELECT DISTINCT age FROM user;

    → 只有 age 一列,对 age 去重。

  • 多列:

    复制代码
    SELECT DISTINCT name, age FROM user;

    → 对 (name, age) 这个列组合 去重,

    → 只有当 (name, age) 都相同时才算重复。

口诀:DISTINCT 作用在 SELECT 后面"所有列的组合"上。


六、WHERE 条件与基础运算符

1. WHERE:永远是"按行过滤"

常见运算符:

  • 比较:=, <>, !=, <, >, <=, >=

  • 范围:BETWEEN a AND b包含 a 和 b)

  • 集合:IN (...) / NOT IN (...)

  • 模糊匹配:LIKE, NOT LIKE

    • %:任意长度

    • _:单个字符

  • NULL 判断:

    • IS NULL / IS NOT NULL
  • 逻辑:AND / OR / NOT

    • 优先级:NOT > AND > OR

2. NULL 判断要点

查 NULL 用 IS,不用 =

  • 错误:age = NULL

  • 正确:age IS NULL


3. LIKE 模糊匹配

  • 名字以 A 开头:

    复制代码
    WHERE name LIKE 'A%';
  • 名字中包含 "abc":

    复制代码
    WHERE name LIKE '%abc%';

七、排序:ORDER BY

复制代码
SELECT id, name, age
FROM user
ORDER BY age DESC, id ASC;

要点:

  • ASC:升序(默认)

  • DESC:降序

  • 支持多列排序:先按前一列排,前一列相等时再看后一列

示例含义:

先按 age 降序,如果同龄,再按 id 升序。
排序只改变结果集顺序不会修改原表数据


八、分页:LIMIT / OFFSET(SQLite / MySQL)

复制代码
SELECT *
FROM user
ORDER BY id
LIMIT 10 OFFSET 20;

含义:

跳过前 20 行,取 10 行(第 21~30 行)。

通用分页公式(page 从 1 开始):

复制代码
LIMIT page_size OFFSET (page - 1) * page_size;

例:第 3 页,每页 20 条:

复制代码
LIMIT 20 OFFSET (3 - 1) * 20 = 40;

性能注意:OFFSET 越大,扫描的行越多,大分页会慢。


九、聚合函数 & 分组:GROUP BY / HAVING

1. 聚合函数(对"一组行"算一个值)

  • COUNT(*):行数

  • SUM(col):总和

  • AVG(col):平均

  • MIN(col) / MAX(col):最小 / 最大

口诀:聚合函数 = 把一堆行"压扁"成一个统计结果。


2. WHERE vs HAVING

  • WHERE

    • GROUP BY 之前

    • 对"行"过滤

  • HAVING

    • GROUP BY 之后

    • 对"组"过滤(可用聚合函数)


3. 示例:统计每个年龄人数,只保留人数 > 5 的年龄段,并倒序

复制代码
SELECT age, COUNT(*) AS cnt
FROM user
WHERE age >= 18          -- 在分组前:先把未成年人过滤掉
GROUP BY age             -- 按年龄分组
HAVING COUNT(*) > 5      -- 在分组后:只保留人数 > 5 的年龄段
ORDER BY cnt DESC;       -- 按人数从多到少排序

理解成一句话:

user 表里,

age 分组,算每个年龄有多少人(cnt),

先过滤掉未成年人,

再只留下人数大于 5 的年龄段,

最后按人数从多到少排序。


十、多表查询:JOIN

1. JOIN 的本质

JOIN = 把多张表"拼在一行里",常用来查详细信息(比如:用户 + 订单)。

表结构示例:

复制代码
CREATE TABLE user (
    id   INTEGER PRIMARY KEY,
    name TEXT
);

CREATE TABLE "order" (
    id      INTEGER PRIMARY KEY,
    user_id INTEGER,
    amount  REAL
);

2. INNER JOIN(内连接)

复制代码
SELECT u.id, u.name, o.amount
FROM user u
JOIN "order" o ON u.id = o.user_id;
-- 等价于 INNER JOIN

只返回两边都能对上号 的记录。

只包含"有订单的用户"。


3. LEFT JOIN(左外连接)

复制代码
SELECT u.id, u.name, o.amount
FROM user u
LEFT JOIN "order" o ON u.id = o.user_id;

左边(user)一个都不能少;

如果右边(order)没有匹配,就用 NULL 填。

典型需求: 查所有用户及其订单金额,没下单的用户金额为 NULL。

→ 使用 LEFT JOIN


4. JOIN vs 子查询(IN / EXISTS)

  • JOIN:

    • 作用:把多表字段拼到一行

    • 场景:查询详细信息(用户 + 订单等)

  • 子查询 + IN / EXISTS:

    • 作用:只用于过滤

    • 场景:判断"是否存在 / 是否在某个集合中"

例:查出有下过订单的用户:

  • IN 写法:

    复制代码
    SELECT *
    FROM user
    WHERE id IN (SELECT user_id FROM "order");
  • EXISTS 写法:

    复制代码
    SELECT *
    FROM user u
    WHERE EXISTS (
        SELECT 1
        FROM "order" o
        WHERE o.user_id = u.id
    );

十一、视图(View)

1. 视图的本质

复制代码
CREATE VIEW user_order_view AS
SELECT u.id   AS user_id,
       u.name,
       o.id   AS order_id,
       o.amount
FROM user u
LEFT JOIN "order" o ON u.id = o.user_id;

视图 = 保存好的 SELECT 查询,本身一般不存数据。

使用视图就像查表:

复制代码
SELECT *
FROM user_order_view
WHERE amount > 100;

2. 视图 vs 表

  • 表(Table):

    • 真正存数据的结构

    • 像 Excel 文件,数据是实打实写进去的

  • 视图(View):

    • 存的是"查询公式"(SELECT ... 定义)

    • 每次查询视图时,实时去访问底层表

    • 像 Excel 里的公式单元格,打开时重新计算

口诀:表存"数据",视图存"查询公式"。


3. 视图的使用场景

  • 封装复杂查询,方便复用(多表 JOIN、分组统计等)

  • 做逻辑隔离:对外只暴露视图,不直接暴露底层表


如果你愿意,下一步我可以帮你把这些内容整理成一份"面试速答版",每个知识点压缩成 1~2 句中文话术 + 1 条典型 SQL,方便你在面试前快速过一遍。

相关推荐
小冷coding1 小时前
【MySQL】MySQL 插入一条数据的完整流程(InnoDB 引擎)
数据库·mysql
Elias不吃糖1 小时前
Java Lambda 表达式
java·开发语言·学习
情缘晓梦.2 小时前
C语言指针进阶
java·开发语言·算法
鲨莎分不晴2 小时前
Redis 基本指令与命令详解
数据库·redis·缓存
专注echarts研发20年2 小时前
工业级 Qt 业务窗体标杆实现・ResearchForm 类深度解析
数据库·qt·系统架构
南知意-3 小时前
IDEA 2025.3 版本安装指南(完整图文教程)
java·intellij-idea·开发工具·idea安装
码农水水4 小时前
蚂蚁Java面试被问:混沌工程在分布式系统中的应用
java·linux·开发语言·面试·职场和发展·php
海边的Kurisu4 小时前
苍穹外卖日记 | Day4 套餐模块
java·苍穹外卖
毕设源码-邱学长4 小时前
【开题答辩全过程】以 走失儿童寻找平台为例,包含答辩的问题和答案
java
Knight_AL4 小时前
用 JOL 验证 synchronized 的锁升级过程(偏向锁 → 轻量级锁 → 重量级锁)
开发语言·jvm·c#