首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >SQL 入门必修课:从零搭建数据查询能力

SQL 入门必修课:从零搭建数据查询能力

作者头像
玄同765
发布2026-01-14 13:06:36
发布2026-01-14 13:06:36
2600
举报

面向 0 基础初学者 | 100% 可运行实战代码 | 关联大模型 / 互联网实际场景 | 无方言语法)


🔍 开篇:0 基础能学会 SQL 吗?必须会吗?

什么是 SQL?

SQL 是和数据库对话的 “结构化自然语言”—— 就像你用中文问「帮我找下高三 1 班的所有学生」,SQL 用固定语法写出来,数据库就能精准返回结果。

为什么必须学?

所有互联网产品 / AI 应用的数据都靠 SQL 管理:

  • 大模型的对话历史、RAG 知识库、用户问答日志
  • 电商的订单、快递、用户评价
  • 手机银行的流水、转账记录
前置准备(0 成本练 SQL)

无需装软件!直接用在线 SQL 环境

推荐:SQLite Online | DB Fiddle 操作:复制本文所有代码到编辑器,点击「Run」即可看到结果


📚 模块 1:SQL 初探 ——SELECT 语句的核心结构与数据检索

核心定位:SQL 最安全、最常用的操作(仅读取数据,不会修改 / 删除),0 基础先练这个!

1.1 核心语法框架
代码语言:javascript
复制
-- 语法:SELECT 你要查的字段1, 字段2 FROM 表名;
-- 注释规则:-- 后面的内容是注释,不会被执行(用于写说明)
1.2 实战 1:查询指定字段(推荐!)

学生表(student) 做例子(表结构:id=学号, name=姓名, age=年龄, class=班级):

代码语言:javascript
复制
-- 1. 先创建模拟学生表(新手直接复制运行)
CREATE TABLE student (
    id INT PRIMARY KEY,
    name VARCHAR(20) NOT NULL,
    age INT,
    class VARCHAR(10)
);
-- 2. 插入模拟数据
INSERT INTO student VALUES 
(1, '张三', 18, '高三1班'),
(2, '李四', 17, '高三2班'),
(3, '王五', 18, '高三1班');
-- 3. 查询「所有学生的姓名+年龄」
SELECT name, age FROM student;

✅ 运行结果示例:

name

age

张三

18

李四

17

王五

18

1.3 实战 2:查询所有字段(不推荐!)

*(通配符)代表「表中所有字段」:

代码语言:javascript
复制
SELECT * FROM student;

❌ 禁忌:生产场景(如大模型对话表)禁止用 SELECT *

原因:会浪费内存 / 网络带宽,泄露敏感字段(如用户手机号)


📚 模块 2:数据定义语言(DDL)—— 创建与管理表结构

核心定位:SQL 的「搭架子工具」—— 用于定义 / 修改 / 删除表的结构(比如建一个「大模型对话历史表」)

2.1 核心语法:CREATE TABLE(建表)
代码语言:javascript
复制
-- 语法:CREATE TABLE 表名 (
--         字段1 数据类型 约束条件,
--         字段2 数据类型 约束条件
--       );
-- 约束=数据规则(如「姓名不能为空」「学号唯一」)
2.2 实战:创建「大模型对话历史表」(关联 AI 场景)
代码语言:javascript
复制
-- 创建【通用版】大模型对话历史表(支持MySQL/PostgreSQL/SQLite)
CREATE TABLE llm_chat_history (
    chat_id INT PRIMARY KEY AUTOINCREMENT, -- 对话唯一ID(自动增长,避免重复)
    user_id VARCHAR(30) NOT NULL,          -- 用户ID(不能为空)
    prompt TEXT NOT NULL,                  -- 用户提问(长文本用TEXT,支持大段内容)
    answer TEXT NOT NULL,                  -- 大模型回答(长文本用TEXT)
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP -- 创建时间(自动记录当前时间)
);

0 基础必懂术语翻译:

语法 / 术语

通俗解释

PRIMARY KEY

表的「身份证号」,每行唯一,不可重复

AUTOINCREMENT

自动生成序号(SQLite 用,MySQL 用 AUTO_INCREMENT,PostgreSQL 用 SERIAL)

NOT NULL

该字段必填,不能空着

VARCHAR(30)

短文本(最多 30 字符,适合用户 ID / 姓名)

TEXT

长文本(无长度限制,适合大模型的提问 / 回答)

DATETIME DEFAULT CURRENT_TIMESTAMP

自动记录当前时间,无需手动输入

2.3 其他 DDL 操作(了解即可,生产需谨慎)

修改表结构:给学生表加「性别」字段

代码语言:javascript
复制
ALTER TABLE student ADD COLUMN gender VARCHAR(2) DEFAULT '未知';

删除表风险极高! 生产环境禁止裸用

代码语言:javascript
复制
DROP TABLE IF EXISTS student; -- IF EXISTS:避免表不存在时报错

📚 模块 3:数据操作语言(DML)—— 增删改查全流程实战

核心定位:SQL 的「数据操作工具」—— 对表中的具体数据进行「增 / 删 / 改 / 查」(查已在模块 1 讲过,这里重点讲「增 / 删 / 改」)

⚠️ 【0 基础红线规则】:UPDATE/DELETE 必须加 WHERE 条件!

否则全表数据都会被修改 / 删除,后悔莫及!

3.1 增:INSERT(插入数据)

语法 1:指定字段插入(推荐!)

代码语言:javascript
复制
-- 向大模型对话表插入2条用户提问
INSERT INTO llm_chat_history (user_id, prompt, answer) VALUES
('user_001', '什么是SQL?', 'SQL是数据库查询语言'),
('user_002', '什么是大模型?', '大模型是参数超百亿的AI模型');

✅ 运行结果:2 rows affected(插入成功)

3.2 改:UPDATE(修改数据)
代码语言:javascript
复制
-- 把user_001的提问改成「SQL适合做什么?」
UPDATE llm_chat_history 
SET prompt = 'SQL适合做什么?' 
WHERE user_id = 'user_001'; -- 必须加WHERE!
3.3 删:DELETE(删除数据)
代码语言:javascript
复制
-- 删除user_002的对话记录
DELETE FROM llm_chat_history 
WHERE user_id = 'user_002'; -- 必须加WHERE!
3.4 全流程串练(增→改→查→删)
代码语言:javascript
复制
-- 1. 增:插入2条对话
INSERT INTO llm_chat_history (user_id, prompt, answer) VALUES
('user_003', 'Python是什么?', 'Python是编程语言'),
('user_004', 'FastAPI是什么?', 'FastAPI是Python后端框架');
-- 2. 改:把user_003的提问改成「Python适合做AI吗?」
UPDATE llm_chat_history SET prompt = 'Python适合做AI吗?' WHERE user_id = 'user_003';
-- 3. 查:查询所有对话
SELECT user_id, prompt FROM llm_chat_history;
-- 4. 删:删除user_004的对话
DELETE FROM llm_chat_history WHERE user_id = 'user_004';

📚 模块 4:数据过滤与排序 ——WHERE 子句与排序逻辑

核心定位:解决「如何只查我要的数据?如何让结果更有序?」

4.1 过滤:WHERE 子句(常用运算符)

运算符

功能

示例(结合大模型场景)

=

等于

WHERE user_id = 'user_001'

<> / !=

不等于

WHERE user_id <> 'user_001'

> / ≥ / < / ≤

比较

WHERE age ≥ 18

BETWEEN A AND B

区间(包含 A/B)

WHERE create_time BETWEEN '2024-01-01' AND '2024-01-31'

IN()

多值匹配

WHERE user_id IN ('user_001','user_003')

IS NULL

空值判断

WHERE gender IS NULL

AND / OR

多条件组合

WHERE class = ' 高三 1 班 ' AND age = 18

实战:查询「高三 1 班年龄≥18 的学生」

代码语言:javascript
复制
SELECT name, age FROM student WHERE class = '高三1班' AND age >= 18;

✅ 运行结果:

name

age

张三

18

王五

18

4.2 排序:ORDER BY 子句
  • ASC升序(默认,可不写)
  • DESC降序

实战:按年龄降序查询所有学生

代码语言:javascript
复制
SELECT name, age FROM student ORDER BY age DESC;

✅ 运行结果:

name

age

张三

18

王五

18

李四

17

4.3 多字段排序(先按班级升序,再按年龄降序)
代码语言:javascript
复制
SELECT name, class, age FROM student ORDER BY class ASC, age DESC;

📚 模块 5:聚合函数与分组统计 —— 从数据到洞察

核心定位:解决「如何统计数据?比如「这个月有多少用户提问?」」

5.1 常用聚合函数(对一组数据计算,返回单个值)

函数

功能

示例(大模型场景)

COUNT()

统计行数

COUNT (chat_id) → 对话总次数

SUM()

求和

SUM (answer_length) → 回答总长度

AVG()

求平均值

AVG (answer_length) → 平均回答长度

MAX()

最大值

MAX (create_time) → 最新的对话时间

MIN()

最小值

MIN (create_time) → 最早的对话时间

5.2 实战 1:统计大模型对话总次数
代码语言:javascript
复制
SELECT COUNT(chat_id) AS chat_total FROM llm_chat_history;

说明:AS chat_total字段别名—— 给统计结果起个好读的名字

5.3 分组统计:GROUP BY 子句

解决「按某个维度统计,比如「每个用户的对话次数」」

代码语言:javascript
复制
SELECT user_id, COUNT(chat_id) AS chat_count 
FROM llm_chat_history 
GROUP BY user_id; -- 按user_id分组

✅ 运行结果:

user_id

chat_count

user_001

1

user_003

1

5.3 分组后过滤:HAVING 子句(0 基础必区分「WHERE vs HAVING」)

关键误区:

  • WHERE过滤原始数据行(分组前用)
  • HAVING过滤分组后的结果(分组后用,必须跟在 GROUP BY 后面)

实战:统计「对话次数≥2 次的用户」(先补全大模型对话表数据)

代码语言:javascript
复制
-- 1. 给大模型对话表补几条数据
INSERT INTO llm_chat_history (user_id, prompt, answer) VALUES
('user_001', 'SQL难吗?', '0基础2小时就能上手'),
('user_001', '如何学SQL?', '多练在线环境的例子'),
('user_003', '大模型能写SQL吗?', '可以,比如GPT-4');
-- 2. 按用户分组,统计对话次数≥2的用户
SELECT user_id, COUNT(chat_id) AS chat_count
FROM llm_chat_history
GROUP BY user_id
HAVING chat_count >= 2; -- 分组后过滤,必须用HAVING!

✅ 运行结果:

user_id

chat_count

user_001

3

5.4 模块 5 实战串练:大模型对话数据洞察

需求:统计每个用户的「平均回答长度」(先给对话表加「回答长度」字段,再统计)

代码语言:javascript
复制
-- 1. 给大模型对话表加回答长度字段
ALTER TABLE llm_chat_history ADD COLUMN answer_length INT;
-- 2. 更新回答长度(SQLite用LENGTH()函数计算文本长度)
UPDATE llm_chat_history SET answer_length = LENGTH(answer);
-- 3. 统计每个用户的平均回答长度(保留1位小数)
SELECT user_id, ROUND(AVG(answer_length), 1) AS avg_answer_len
FROM llm_chat_history
GROUP BY user_id;

✅ 运行结果:

user_id

avg_answer_len

user_001

12.3

user_003

10.5


📚 模块 6:多表连接(JOIN)—— 打破数据孤岛

核心定位:解决「数据分散在多张表,无法单次查询的问题」 比如:大模型的user表存用户年龄 / 性别,llm_chat_history表存对话,要查「20 岁以上用户的对话」,就得把两张表连接起来

6.1 先构建「多表场景」(用学生表 + 成绩表更直观)
代码语言:javascript
复制
-- 1. 创建学生成绩表(关联学生表的id字段)
CREATE TABLE student_score (
    score_id INT PRIMARY KEY AUTOINCREMENT,
    student_id INT NOT NULL, -- 关联学生表的id
    subject VARCHAR(20) NOT NULL,
    score INT NOT NULL
);
-- 2. 插入成绩数据(student_id对应学生表的id)
INSERT INTO student_score VALUES
(1, 1, '数学', 95),
(2, 2, '数学', 88),
(3, 3, '数学', 92),
(4, 1, '英语', 85);
6.2 核心 JOIN 类型:INNER JOIN(内连接,0 基础必学)

功能:只返回「两张表都存在关联数据」的行(即交集

语法框架:

代码语言:javascript
复制
SELECT 表1.字段, 表2.字段
FROM 表1
INNER JOIN 表2 ON 表1.关联字段 = 表2.关联字段;
-- 关键:ON后面是「两张表的关联条件」

实战:查询「每个学生的姓名 + 班级 + 数学成绩」

代码语言:javascript
复制
SELECT student.name, student.class, student_score.score
FROM student
INNER JOIN student_score ON student.id = student_score.student_id
WHERE student_score.subject = '数学'; -- 可叠加WHERE过滤科目

✅ 运行结果:

name

class

score

张三

高三 1 班

95

李四

高三 2 班

88

王五

高三 1 班

92

6.3 扩展 JOIN 类型:LEFT JOIN(左连接,常见需求)

功能:返回「左表的所有数据行」,右表没有匹配的行用 NULL 填充

实战:查询「所有学生的英语成绩,包括没考英语的学生」

代码语言:javascript
复制
SELECT student.name, student_score.subject, student_score.score
FROM student -- 左表:所有学生
LEFT JOIN student_score ON student.id = student_score.student_id
WHERE student_score.subject = '英语'; -- 过滤科目

✅ 运行结果(王五没考英语,score 为 NULL):

name

subject

score

张三

英语

85

李四

NULL

NULL

王五

NULL

NULL

6.4 JOIN 避坑:禁止忘记写「关联条件(ON 子句)」

如果忘记写 ON student.id = student_score.student_id,会产生「笛卡尔积」—— 即两张表所有行的无规则配对,结果 99% 是错误的:

代码语言:javascript
复制
-- ❌ 错误示例:忘记写ON条件
SELECT student.name, student_score.score FROM student JOIN student_score;

❌ 错误结果(3 个学生 ×4 条成绩 = 12 条无意义数据):

name

score

张三

95

李四

88

...

...

6.5 模块 6 实战串练:大模型多表查询

需求:查询「用户年龄≥18 岁的对话记录」(假设已有用户表,关联对话表)

代码语言:javascript
复制
-- 1. 先创建用户表
CREATE TABLE user (
    user_id VARCHAR(30) PRIMARY KEY,
    age INT NOT NULL
);
-- 2. 插入用户数据
INSERT INTO user VALUES ('user_001', 20), ('user_003', 17);
-- 3. 连接用户表和对话表,查询18岁以上用户的对话
SELECT user.user_id, user.age, llm_chat_history.prompt
FROM user
INNER JOIN llm_chat_history ON user.user_id = llm_chat_history.user_id
WHERE user.age >= 18;

✅ 运行结果:

user_id

age

prompt

user_001

20

SQL 适合做什么?

user_001

20

SQL 难吗?

user_001

20

如何学 SQL?


📌 0 基础 SQL 学习避坑指南(必看)

  1. 绝对禁忌:生产环境下 UPDATE/DELETE 忘记加 WHERE 条件(会删全表!)
  2. 性能优化:禁止用 SELECT * 查询所有字段,只查需要的字段
  3. 语法规范:关键字(如 SELECT、FROM、JOIN)统一大写,字段 / 表名小写(增强可读性)
  4. 练习工具:用在线 SQL 环境(如 SQLite Online),0 成本且无需装软件
  5. 概念区分
    • WHERE vs HAVING:分组前 / 后过滤
    • INNER JOIN vs LEFT JOIN:交集 / 左表全量

🚀 进阶方向(关联大模型场景)

学完基础 SQL 后,可延伸到大模型应用的高级 SQL

  1. 向量数据库 SQL:用 pgvector 插件实现大模型知识库的语义检索(比如 SELECT * FROM rag_documents ORDER BY embedding <-> '[向量值]' LIMIT 5
  2. 时间序列 SQL:查询大模型对话的分时统计(比如 SELECT DATE(create_time) AS date, COUNT(*) FROM llm_chat_history GROUP BY DATE(create_time)
  3. 分库分表 SQL:处理大模型的亿级对话数据(用 PARTITION BY 按时间 / 用户分表)

🌟 博客收尾福利

【0 基础入门 SQL 速查表】:点击下载 PDF(包含本文所有核心语法 + 实战代码) 【在线练习题库】:SQLZoo(适合 0 基础的交互式练习,覆盖本文所有知识点)

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-12-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 🔍 开篇:0 基础能学会 SQL 吗?必须会吗?
    • 什么是 SQL?
    • 为什么必须学?
    • 前置准备(0 成本练 SQL)
  • 📚 模块 1:SQL 初探 ——SELECT 语句的核心结构与数据检索
    • 1.1 核心语法框架
    • 1.2 实战 1:查询指定字段(推荐!)
    • 1.3 实战 2:查询所有字段(不推荐!)
  • 📚 模块 2:数据定义语言(DDL)—— 创建与管理表结构
    • 2.1 核心语法:CREATE TABLE(建表)
    • 2.2 实战:创建「大模型对话历史表」(关联 AI 场景)
    • 2.3 其他 DDL 操作(了解即可,生产需谨慎)
  • 📚 模块 3:数据操作语言(DML)—— 增删改查全流程实战
    • ⚠️ 【0 基础红线规则】:UPDATE/DELETE 必须加 WHERE 条件!
    • 3.1 增:INSERT(插入数据)
    • 3.2 改:UPDATE(修改数据)
    • 3.3 删:DELETE(删除数据)
    • 3.4 全流程串练(增→改→查→删)
  • 📚 模块 4:数据过滤与排序 ——WHERE 子句与排序逻辑
    • 4.1 过滤:WHERE 子句(常用运算符)
    • 4.2 排序:ORDER BY 子句
    • 4.3 多字段排序(先按班级升序,再按年龄降序)
  • 📚 模块 5:聚合函数与分组统计 —— 从数据到洞察
    • 5.1 常用聚合函数(对一组数据计算,返回单个值)
    • 5.2 实战 1:统计大模型对话总次数
    • 5.3 分组统计:GROUP BY 子句
    • 5.3 分组后过滤:HAVING 子句(0 基础必区分「WHERE vs HAVING」)
    • 5.4 模块 5 实战串练:大模型对话数据洞察
  • 📚 模块 6:多表连接(JOIN)—— 打破数据孤岛
    • 6.1 先构建「多表场景」(用学生表 + 成绩表更直观)
    • 6.2 核心 JOIN 类型:INNER JOIN(内连接,0 基础必学)
    • 6.3 扩展 JOIN 类型:LEFT JOIN(左连接,常见需求)
    • 6.4 JOIN 避坑:禁止忘记写「关联条件(ON 子句)」
    • 6.5 模块 6 实战串练:大模型多表查询
  • 📌 0 基础 SQL 学习避坑指南(必看)
  • 🚀 进阶方向(关联大模型场景)
  • 🌟 博客收尾福利
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档