Skip to content

SQL知识点大全(新手友好版)

一、SQL 基础与核心概念

1. 什么是SQL?

SQL是一种专门用来与数据库沟通的语言。通过SQL,你可以执行数据的查询、更新、插入和删除,以及创建和修改数据库结构等操作。

2. 数据库与表

  • 数据库 (Database):一个有组织的数据集合,通常存储在计算机系统中。可以把它想象成一个大柜子。
  • 表 (Table):数据库中的基本存储单位,由行 (Row) 和列 (Column) 组成。可以把它想象成柜子里的抽屉,每个抽屉里存放着特定类型的信息。
    • 列 (Column/Field):表中的一个字段,代表一种特定类型的数据(如:姓名、年龄、成绩)。
    • 行 (Row/Record):表中的一条记录,代表一组相关的数据(如:某个学生的完整信息)。
    • 主键 (Primary Key):表中唯一标识每一行的列(或列组合)。例如学生表中的学号。
    • 外键 (Foreign Key):一个表中的列,其值引用另一个表的主键。用于建立表与表之间的关联。

3. SQL命令分类

SQL命令主要可以分为以下几类:

  • DDL (Data Definition Language - 数据定义语言):用于定义和管理数据库对象。
    • CREATE:创建数据库、表、视图、索引等。
    • ALTER:修改数据库、表等结构。
    • DROP:删除数据库、表等。
    • TRUNCATE:快速删除表中的所有行,但保留表结构。
  • DML (Data Manipulation Language - 数据操作语言):用于操作数据库中的数据。
    • SELECT:查询数据。
    • INSERT:插入数据。
    • UPDATE:更新数据。
    • DELETE:删除数据。
  • DCL (Data Control Language - 数据控制语言):用于控制数据库的访问权限。
    • GRANT:授予权限。
    • REVOKE:撤销权限。
  • TCL (Transaction Control Language - 事务控制语言):用于管理数据库事务。
    • COMMIT:提交事务,将更改永久保存。
    • ROLLBACK:回滚事务,撤销未提交的更改。
    • SAVEPOINT:在事务中设置保存点。

二、常用SQL语句用法

假设我们有以下两个表:

Students (学生表)

StudentID (学号)Name (姓名)Age (年龄)Major (专业)
1张三20计算机科学
2李四22数学
3王五21计算机科学
4赵六20物理学

Courses (课程表)

CourseID (课程号)CourseName (课程名)Teacher (教师)
C01数据库原理刘老师
C02高等数学陈老师
C03大学物理张老师

1. SELECT - 查询数据

SELECT 是SQL中最常用的语句,用于从数据库表中检索数据。

基本语法:

sql
SELECT column1, column2, ...
FROM table_name;
  • 查询所有列:

    sql
    SELECT *
    FROM Students;
    -- 结果: 返回 Students 表中的所有行和所有列
  • 查询指定列:

    sql
    SELECT Name, Major
    FROM Students;
    -- 结果: 返回 Students 表中所有学生的姓名和专业

2. WHERE - 条件过滤

WHERE 子句用于根据指定的条件过滤记录。

基本语法:

sql
SELECT column1, column2, ...
FROM table_name
WHERE condition;
  • 常用比较运算符: =, >, <, >=, <=, != (或 <>)
  • 逻辑运算符: AND, OR, NOT
  • 其他常用条件:
    • BETWEEN ... AND ...:在某个范围内
    • IN (...):在指定的一组值中
    • LIKE:模糊查询(% 代表零个或多个字符,_ 代表一个字符)
    • IS NULL / IS NOT NULL:检查是否为空值

示例:

  • 查询专业为“计算机科学”的学生:

    sql
    SELECT Name, Age
    FROM Students
    WHERE Major = '计算机科学';
    -- 结果: 张三 (20), 王五 (21)
  • 查询年龄大于20岁且专业为“计算机科学”的学生:

    sql
    SELECT *
    FROM Students
    WHERE Age > 20 AND Major = '计算机科学';
    -- 结果: 王五 (21, 计算机科学)
  • 查询姓名以“张”开头的学生:

    sql
    SELECT *
    FROM Students
    WHERE Name LIKE '张%';
    -- 结果: 张三
  • 查询专业是“数学”或“物理学”的学生:

    sql
    SELECT *
    FROM Students
    WHERE Major IN ('数学', '物理学');
    -- 结果: 李四 (数学), 赵六 (物理学)

3. ORDER BY - 结果排序

ORDER BY 子句用于对结果集进行排序,默认为升序 (ASC),可指定降序 (DESC)。

基本语法:

sql
SELECT column1, column2, ...
FROM table_name
ORDER BY column_to_sort ASC|DESC;

示例:

  • 按年龄升序排列所有学生:

    sql
    SELECT *
    FROM Students
    ORDER BY Age ASC; -- ASC 可以省略
    -- 结果: 张三(20), 赵六(20), 王五(21), 李四(22)
  • 按年龄降序排列,如果年龄相同则按学号升序:

    sql
    SELECT *
    FROM Students
    ORDER BY Age DESC, StudentID ASC;

4. LIMIT / TOP - 限制结果数量

用于限制查询返回的记录数量。不同数据库系统语法不同:

  • MySQL, PostgreSQL: LIMIT
  • SQL Server: TOP
  • Oracle: ROWNUM (通常结合子查询使用)

MySQL/PostgreSQL 示例:

sql
SELECT *
FROM Students
LIMIT 2; -- 返回前2条记录

SELECT *
FROM Students
ORDER BY Age DESC
LIMIT 1 OFFSET 1; -- 跳过第1条,取接下来1条 (即按年龄降序的第2个)

SQL Server 示例:

sql
SELECT TOP 2 *
FROM Students; -- 返回前2条记录

5. INSERT INTO - 插入数据

用于向表中添加新的记录。

基本语法:

sql
INSERT INTO table_name (column1, column2, ...)
VALUES (value1, value2, ...);

如果为所有列都提供值,并且顺序与表中列的顺序一致,可以省略列名:

sql
INSERT INTO table_name
VALUES (value1_for_col1, value2_for_col2, ...);

示例:

sql
INSERT INTO Students (StudentID, Name, Age, Major)
VALUES (5, '孙七', 19, '英语');

-- 如果按表列顺序插入所有值
INSERT INTO Courses
VALUES ('C04', '线性代数', '王老师');

6. UPDATE - 更新数据

用于修改表中已存在的记录。务必使用 WHERE 子句,否则会更新表中的所有行!

基本语法:

sql
UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;

示例:

sql
UPDATE Students
SET Major = '软件工程'
WHERE StudentID = 1; -- 将学号为1的学生的专业改为软件工程

UPDATE Students
SET Age = Age + 1
WHERE Major = '计算机科学'; -- 将所有计算机科学专业的学生年龄增加1岁

7. DELETE - 删除数据

用于从表中删除记录。务必使用 WHERE 子句,否则会删除表中的所有行!

基本语法:

sql
DELETE FROM table_name
WHERE condition;

示例:

sql
DELETE FROM Students
WHERE StudentID = 5; -- 删除学号为5的学生记录

-- 如果要删除表内所有数据(但保留表结构)
-- DELETE FROM Students; (不推荐,效率低,会记录日志)
-- TRUNCATE TABLE Students; (推荐,效率高,不记录日志,不可回滚)

8. CREATE TABLE - 创建表

用于在数据库中创建新表。

基本语法:

sql
CREATE TABLE table_name (
    column1 datatype constraints,
    column2 datatype constraints,
    ...
    PRIMARY KEY (one_or_more_columns) -- 定义主键
);

常用数据类型:INT (整数), VARCHAR(n) (可变长度字符串), CHAR(n) (固定长度字符串), DATE, DATETIME, DECIMAL(p,s) (精确小数)等。 常用约束:NOT NULL (非空), UNIQUE (唯一), PRIMARY KEY (主键), FOREIGN KEY (外键), CHECK (检查约束)。

示例:

sql
CREATE TABLE Enrollments (
    EnrollmentID INT PRIMARY KEY,
    StudentID INT,
    CourseID VARCHAR(10),
    Grade CHAR(1),
    FOREIGN KEY (StudentID) REFERENCES Students(StudentID), -- 外键关联到Students表的StudentID
    FOREIGN KEY (CourseID) REFERENCES Courses(CourseID)   -- 外键关联到Courses表的CourseID
);

9. ALTER TABLE - 修改表结构

用于添加、删除或修改表的列。

示例:

  • 添加列:
    sql
    ALTER TABLE Students
    ADD COLUMN Email VARCHAR(100);
  • 修改列数据类型:
    sql
    ALTER TABLE Students
    ALTER COLUMN Age TYPE SMALLINT; -- PostgreSQL语法,MySQL用 MODIFY COLUMN Age SMALLINT; SQL Server用 ALTER COLUMN Age SMALLINT;
  • 删除列:
    sql
    ALTER TABLE Students
    DROP COLUMN Email;

10. DROP TABLE - 删除表

用于从数据库中永久删除一个表及其所有数据。

sql
DROP TABLE Enrollments;

三、进阶SQL知识点

1. 聚合函数 (Aggregate Functions) 与 GROUP BY

聚合函数对一组值进行计算,并返回单个值。

  • COUNT(*)COUNT(column_name): 计算行数或某列非空值的数量。
  • SUM(column_name): 计算某列数值的总和。
  • AVG(column_name): 计算某列数值的平均值。
  • MAX(column_name): 找出某列的最大值。
  • MIN(column_name): 找出某列的最小值。

GROUP BY 子句通常与聚合函数一起使用,将结果集中的行按一个或多个列的值进行分组,然后对每个组应用聚合函数。

基本语法:

sql
SELECT column_to_group_by, AGGREGATE_FUNCTION(column_name)
FROM table_name
WHERE condition
GROUP BY column_to_group_by;

示例:

  • 统计每个专业的学生人数:

    sql
    SELECT Major, COUNT(*) AS NumberOfStudents
    FROM Students
    GROUP BY Major;
    -- 结果:
    -- 计算机科学 | 2
    -- 数学       | 1
    -- 物理学     | 1
  • 统计每个专业学生的平均年龄:

    sql
    SELECT Major, AVG(Age) AS AverageAge
    FROM Students
    GROUP BY Major;

2. HAVING - 分组后过滤

HAVING 子句用于在 GROUP BY 分组之后对分组结果进行过滤。WHERE 是在分组前过滤行,HAVING 是在分组后过滤组。

基本语法:

sql
SELECT column_to_group_by, AGGREGATE_FUNCTION(column_name)
FROM table_name
WHERE condition -- 过滤行
GROUP BY column_to_group_by
HAVING aggregate_condition; -- 过滤组

示例:

  • 查询学生人数超过1人的专业:
    sql
    SELECT Major, COUNT(*) AS NumberOfStudents
    FROM Students
    GROUP BY Major
    HAVING COUNT(*) > 1;
    -- 结果: 计算机科学 | 2

3. JOIN - 表连接

JOIN 用于根据两个或多个表中的相关列将它们组合起来。

  • INNER JOIN (或 JOIN): 返回两个表中连接字段匹配的行。

    sql
    SELECT s.Name, c.CourseName
    FROM Students s
    INNER JOIN Enrollments e ON s.StudentID = e.StudentID
    INNER JOIN Courses c ON e.CourseID = c.CourseID;
    -- 假设 Enrollments 表中有数据,这将列出学生姓名和他们选修的课程名
  • LEFT JOIN (或 LEFT OUTER JOIN): 返回左表中的所有行,以及右表中匹配的行。如果右表中没有匹配,则结果中右表的列为NULL。

    sql
    SELECT s.Name, c.CourseName
    FROM Students s
    LEFT JOIN Enrollments e ON s.StudentID = e.StudentID
    LEFT JOIN Courses c ON e.CourseID = c.CourseID;
    -- 列出所有学生,以及他们选修的课程名。如果学生没选课,课程名部分为NULL
  • RIGHT JOIN (或 RIGHT OUTER JOIN): 返回右表中的所有行,以及左表中匹配的行。如果左表中没有匹配,则结果中左表的列为NULL。

    sql
    SELECT s.Name, c.CourseName
    FROM Students s
    RIGHT JOIN Enrollments e ON s.StudentID = e.StudentID
    RIGHT JOIN Courses c ON e.CourseID = c.CourseID;
    -- 列出所有被选的课程,以及选修该课程的学生。如果课程没人选,学生姓名部分为NULL (假设Enrollments和Courses有数据)
  • FULL OUTER JOIN (或 FULL JOIN): 返回左表和右表中的所有行。如果某行在另一个表中没有匹配,则另一个表的列为NULL。

    sql
    SELECT s.Name, c.CourseName
    FROM Students s
    FULL OUTER JOIN Enrollments e ON s.StudentID = e.StudentID
    FULL OUTER JOIN Courses c ON e.CourseID = c.CourseID;
    -- 列出所有学生和所有课程,显示匹配关系,不匹配则为NULL

4. 子查询 (Subquery)

子查询是嵌套在另一个SQL查询(主查询)中的查询。它可以出现在 SELECT, FROM, WHERE, HAVING 子句中。

示例:

  • 查询年龄大于平均年龄的学生:

    sql
    SELECT Name, Age
    FROM Students
    WHERE Age > (SELECT AVG(Age) FROM Students);
  • 查询选修了“数据库原理”课程的学生姓名 (假设 Enrollments 表中有 StudentIDCourseID):

    sql
    SELECT Name
    FROM Students
    WHERE StudentID IN (
        SELECT StudentID
        FROM Enrollments
        WHERE CourseID = (SELECT CourseID FROM Courses WHERE CourseName = '数据库原理')
    );

5. UNIONUNION ALL

用于合并两个或多个 SELECT 语句的结果集。

  • UNION: 合并结果集,并自动去除重复的行。
  • UNION ALL: 合并结果集,包含所有行,包括重复行。

要求: 所有 SELECT 语句必须具有相同数量的列,列也必须具有相似的数据类型,并且列的顺序也必须相同。

示例:

sql
SELECT Name, Major FROM Students WHERE Age > 20
UNION
SELECT Name, Major FROM Students WHERE Major = '计算机科学';
-- 合并两个查询结果,并去重

6. 视图 (View)

视图是一个虚拟表,其内容由查询定义。视图本身不存储数据,数据仍然存储在基表中。

创建视图:

sql
CREATE VIEW CS_Students AS
SELECT StudentID, Name, Age
FROM Students
WHERE Major = '计算机科学';

之后可以像查询表一样查询视图:

sql
SELECT * FROM CS_Students;

优点:

  • 简化复杂查询。
  • 提高安全性(只暴露部分数据)。
  • 数据独立性(基表结构改变,如果视图定义不涉及改变的列,视图仍可用)。

7. 索引 (Index)

索引是数据库表中一列或多列值的排序列表,用于加快查询速度。 创建索引会占用额外的存储空间,并可能降低写操作(INSERT, UPDATE, DELETE)的速度,因为索引也需要更新。

创建索引:

sql
CREATE INDEX idx_student_major ON Students (Major);
-- 在 Students 表的 Major 列上创建索引

查询 WHERE Major = 'xxx' 时会更快。

8. 事务 (Transaction)

事务是一组SQL操作,这些操作要么全部成功执行,要么全部失败回滚,以确保数据的一致性和完整性。 事务具有ACID特性:

  • 原子性 (Atomicity): 事务是不可分割的最小工作单元,要么都做,要么都不做。
  • 一致性 (Consistency): 事务执行前后,数据库从一个一致性状态转变到另一个一致性状态。
  • 隔离性 (Isolation): 一个事务的执行不应被其他并发事务干扰。
  • 持久性 (Durability): 一旦事务提交,其结果就是永久性的。

常用命令:

  • BEGIN TRANSACTION (或 START TRANSACTION): 开始一个事务。
  • COMMIT: 提交事务,将所有更改永久保存到数据库。
  • ROLLBACK: 回滚事务,撤销自上次COMMITROLLBACK以来的所有更改。
sql
BEGIN TRANSACTION;
UPDATE Students SET Age = 21 WHERE StudentID = 1;
-- 假设这里有一个错误或者条件不满足
IF some_condition_is_false THEN
    ROLLBACK;
ELSE
    COMMIT;
END IF;

9. 窗口函数 (Window Functions) - (较进阶)

窗口函数对一组与当前行相关的表行(称为窗口)执行计算。与聚合函数不同,窗口函数不会将多行聚合成单行,而是为结果集中的每一行都返回一个值。

常见窗口函数:

  • 排名函数: ROW_NUMBER(), RANK(), DENSE_RANK()
  • 聚合窗口函数: SUM() OVER (...), AVG() OVER (...)
  • 值函数: LAG(), LEAD()

示例:

  • 按专业给学生排名(按年龄从小到大):
    sql
    SELECT
        Name,
        Major,
        Age,
        ROW_NUMBER() OVER (PARTITION BY Major ORDER BY Age ASC) as RankInMajor
    FROM Students;
    -- PARTITION BY Major: 按专业分组(窗口)
    -- ORDER BY Age ASC: 在每个窗口内按年龄排序

10. 公用表表达式 (Common Table Expressions - CTEs) - (较进阶)

CTE 是一个临时的、命名的结果集,可以在单个SQL语句(如 SELECT, INSERT, UPDATE, DELETECREATE VIEW)的执行范围内引用。

基本语法:

sql
WITH cte_name (column1, column2, ...) AS (
    -- CTE 查询定义
    SELECT ...
)
-- 主查询,可以引用 cte_name
SELECT * FROM cte_name;

示例:

  • 找出每个专业中最年轻的学生:
    sql
    WITH RankedStudents AS (
        SELECT
            Name,
            Major,
            Age,
            ROW_NUMBER() OVER (PARTITION BY Major ORDER BY Age ASC) as rn
        FROM Students
    )
    SELECT Name, Major, Age
    FROM RankedStudents
    WHERE rn = 1;

四、学习建议

  1. 动手实践:理论学习后,最重要的是动手写SQL。找一个数据库环境(如MySQL, PostgreSQL, SQLite),创建表,插入数据,然后练习各种查询。
  2. 理解数据模型:学会看懂ER图(实体关系图),理解表与表之间的关系,这对写出正确的JOIN查询至关重要。
  3. 从简单到复杂:先掌握基础的SELECT, WHERE, INSERT, UPDATE, DELETE,再逐步学习GROUP BY, JOIN, 子查询等。
  4. 查阅文档:不同的数据库系统(MySQL, PostgreSQL, SQL Server, Oracle等)在SQL语法上可能略有差异,遇到问题时查阅对应数据库的官方文档。
  5. 多看示例:通过看别人写的SQL语句,学习不同的写法和技巧。

希望这份介绍对你入门SQL有所帮助!记住,多练习是学好SQL的关键。