SQL Server 核心语法+进阶知识点大全(小白版)

SQL Server 核心语法+进阶知识点大全(小白版)

前言

本文整理了SQL Server从基础语法高阶实战 的全量核心内容,涵盖数据查询、操作、表结构管理、聚合分组、多表联查、索引、事务、存储过程等,全程搭配易懂示例+注释,兼顾新手入门和日常开发查阅,适合快速上手并掌握实际开发所需的95%+语法。

一、基础查询(SELECT):核心数据检索

1. 基础语法

sql 复制代码
SELECT [ALL | DISTINCT] 列名1, 列名2, ...  -- ALL默认显示所有行,DISTINCT去重
FROM 表名
[WHERE 筛选条件]  -- 过滤行数据
[ORDER BY 列名 [ASC | DESC]]  -- 排序,ASC升序(默认),DESC降序
[TOP n [PERCENT]];  -- 限制返回行数,PERCENT表示百分比

2. 实战示例

sql 复制代码
-- 1. 查询所有列(开发中尽量少用*,指定列更高效)
SELECT * FROM Student;

-- 2. 查询指定列,去重,按成绩降序取前10条
-- 标准正确写法(所有SQL Server版本都支持)
SELECT DISTINCT TOP 10 Name, Score 
FROM Student 
WHERE Age > 18 
ORDER BY Score DESC;

-- 3. 取前20%的学生姓名
SELECT TOP 20 PERCENT Name FROM Student;

二、数据操作(DML):增删改表数据

1. 插入数据(INSERT)

sql 复制代码
-- 格式1:指定列插入(推荐,表结构变更不影响)
INSERT INTO 表名 (列1, 列2, ...)
VALUES (值1, 值2, ...);

-- 格式2:批量插入(高效,减少数据库交互)
INSERT INTO 表名 (列1, 列2)
VALUES (值1, 值2), (值3, 值4), (值5, 值6);

-- 示例
INSERT INTO Student (Name, Age, Score)
VALUES ('张三', 20, 90), ('李四', 19, 85);

2. 更新数据(UPDATE)

sql 复制代码
-- 语法:WHERE条件必加!否则更新全表数据
UPDATE 表名
SET 列1 = 值1, 列2 = 值2, ...
[WHERE 筛选条件];

-- 示例:更新张三的成绩为95
UPDATE Student
SET Score = 95
WHERE Name = '张三';

3. 删除数据(DELETE)

sql 复制代码
-- 语法:WHERE条件必加!否则删除全表数据
DELETE FROM 表名
[WHERE 筛选条件];

-- 示例:删除年龄小于18的学生
DELETE FROM Student
WHERE Age < 18;

-- 清空表(自增列重置,速度远快于DELETE,不可回滚)
TRUNCATE TABLE Student;

核心区别DELETE可回滚、可加条件;TRUNCATE不可回滚、无条件,适合清空全表。

三、表结构操作(DDL):创建/修改/删除表

1. 创建表(CREATE TABLE)

sql 复制代码
CREATE TABLE 表名 (
    列名1 数据类型 [约束],
    列名2 数据类型 [约束],
    ...
);

-- 示例:学生表(含主键、自增、非空、默认值约束)
CREATE TABLE Student (
    Id INT IDENTITY(1,1) PRIMARY KEY,  -- IDENTITY(起始值,步长):自增列,主键默认是聚集索引
    Name VARCHAR(50) NOT NULL,         -- 非空约束
    Age INT CHECK (Age >= 0),          -- 检查约束:年龄非负
    Score DECIMAL(5,2),                -- 小数:总位数5,小数位2(如99.99)
    CreateTime DATETIME DEFAULT GETDATE(),  -- 默认值:当前系统时间
    ClassId INT  -- 关联班级表,后续加外键
);

2. 修改表(ALTER TABLE)

sql 复制代码
-- 1. 添加列
ALTER TABLE 表名 ADD 列名 数据类型 [约束];
ALTER TABLE Student ADD Gender CHAR(1) DEFAULT '男';

-- 2. 修改列(数据类型/长度)
ALTER TABLE 表名 ALTER COLUMN 列名 新数据类型;
ALTER TABLE Student ALTER COLUMN Name VARCHAR(100);

-- 3. 删除列
ALTER TABLE 表名 DROP COLUMN 列名;
ALTER TABLE Student DROP COLUMN Gender;

-- 4. 添加外键约束(关联两张表)
ALTER TABLE Student ADD CONSTRAINT FK_Student_Class
FOREIGN KEY (ClassId) REFERENCES Class(Id);

3. 删除表(DROP TABLE)

sql 复制代码
-- IF EXISTS:SQL Server2016+支持,避免表不存在时报错
DROP TABLE [IF EXISTS] 表名;
DROP TABLE IF EXISTS Student;

四、聚合函数+分组(GROUP BY/HAVING):数据统计分析

1. 常用聚合函数

函数 作用 注意点
COUNT(*) 统计总行数 包含NULL值
COUNT(列名) 统计指定列非NULL值行数 排除NULL值
SUM(列名) 求指定列数值和 仅支持数值类型
AVG(列名) 求指定列平均值 仅支持数值类型,排除NULL
MAX(列名) 求指定列最大值 支持数值/日期/字符串
MIN(列名) 求指定列最小值 支持数值/日期/字符串

2. 语法与示例

sql 复制代码
-- 格式:WHERE筛选分组前数据,HAVING筛选分组后数据
SELECT 分组列, 聚合函数(列名) AS 别名
FROM 表名
[WHERE 分组前条件]
GROUP BY 分组列  -- 分组列必须与SELECT非聚合列一致
[HAVING 聚合函数条件];

-- 示例:按年龄分组,统计及格(≥60)学生数,且每组人数>2
SELECT Age, COUNT(*) AS StudentCount
FROM Student
WHERE Score >= 60
GROUP BY Age
HAVING COUNT(*) > 2;

五、多表联查(JOIN):基础→高阶实战

1. 基础连接类型(2表联查)

核心 :通过关联列(如主键/外键)拼接多张表的数,结果集按匹配规则返回。

连接类型 通俗解释 结果集
INNER JOIN 只找「两边都有」的数据 仅返回两表匹配的行
LEFT JOIN 左表全要,右表补NULL 左表所有行 + 右表匹配行(无则NULL)
RIGHT JOIN 右表全要,左表补NULL 右表所有行 + 左表匹配行(无则NULL)
FULL JOIN 两边数据全要 两表所有行(无匹配则补NULL)

2. 2表联查示例

先创建关联表用于测试:

sql 复制代码
-- 班级表
CREATE TABLE Class (
    Id INT IDENTITY(1,1) PRIMARY KEY,
    ClassName VARCHAR(50) NOT NULL,
    Teacher VARCHAR(50)
);
-- 成绩表
CREATE TABLE Score (
    Id INT IDENTITY(1,1) PRIMARY KEY,
    StudentId INT FOREIGN KEY REFERENCES Student(Id),
    Subject VARCHAR(20) NOT NULL,
    Score DECIMAL(5,2) NOT NULL
);

联查实战:

sql 复制代码
-- 1. INNER JOIN:查询有成绩的学生姓名+科目+成绩(仅返回两边匹配数据)
SELECT s.Name, sc.Subject, sc.Score
FROM Student s  -- 表别名:简化代码
INNER JOIN Score sc ON s.Id = sc.StudentId;  -- ON:关联条件

-- 2. LEFT JOIN:查询所有学生+成绩(无成绩的学生也显示,成绩列补NULL)
SELECT s.Name, sc.Subject, sc.Score
FROM Student s
LEFT JOIN Score sc ON s.Id = sc.StudentId;

-- 3. RIGHT JOIN:查询所有成绩+对应学生(无学生的成绩也显示,学生列补NULL)
SELECT s.Name, sc.Subject, sc.Score
FROM Student s
RIGHT JOIN Score sc ON s.Id = sc.StudentId;

3. 高阶:3表及以上联查(开发高频场景)

核心逻辑 :先联查2张表,再将结果与第3张表联查,关联条件依次叠加

sql 复制代码
-- 示例:查询「学生姓名+所属班级+科目+成绩」(3表联查:Student+Class+Score)
SELECT s.Name, c.ClassName, sc.Subject, sc.Score
FROM Student s
-- 第一步:学生表联班级表(通过ClassId)
LEFT JOIN Class c ON s.ClassId = c.Id
-- 第二步:结果联成绩表(通过StudentId)
LEFT JOIN Score sc ON s.Id = sc.StudentId
-- 额外筛选:只看数学成绩
WHERE sc.Subject = '数学';

六、子查询:嵌套查询的核心用法

1. 什么是子查询

一个查询结果 作为另一个查询的条件/数据源/列值 ,用()包裹,适用于复杂的分步查询,小白可理解为「先算内层,再算外层」。

2. 常用场景示例

sql 复制代码
-- 场景1:子查询作为WHERE条件(IN/EXISTS/比较运算符)
-- 示例:查询成绩大于数学平均分的学生姓名
SELECT Name 
FROM Student 
WHERE Id IN (
    -- 内层:查数学成绩大于平均分的StudentId
    SELECT StudentId 
    FROM Score 
    WHERE Subject = '数学' AND Score > (
        -- 内层的内层:查数学平均分
        SELECT AVG(Score) FROM Score WHERE Subject = '数学'
    )
);

-- 场景2:子查询作为数据源(派生表,需加别名)
-- 示例:查询各年龄组的学生数,且仅显示人数>1的组
SELECT t.Age, t.StudentCount
FROM (
    -- 内层:按年龄分组统计人数,作为派生表t
    SELECT Age, COUNT(*) AS StudentCount 
    FROM Student 
    GROUP BY Age
) AS t
WHERE t.StudentCount > 1;

-- 场景3:子查询作为列值
-- 示例:查询学生姓名+最新一次的数学成绩
SELECT 
    Name,
    -- 内层:查该学生的最新数学成绩(按成绩降序取1条)
    (SELECT TOP 1 Score FROM Score WHERE StudentId = s.Id AND Subject = '数学' ORDER BY Score DESC) AS LatestMathScore
FROM Student s;

七、常用内置函数:字符串/日期/数值(开发高频)

1. 字符串函数

sql 复制代码
SELECT 
    CONCAT('姓名:', Name) AS 拼接结果,  -- 字符串拼接
    SUBSTRING(Name, 1, 2) AS 截取前2位,  -- 截取(起始位置从1开始)
    REPLACE(Name, '张', '章') AS 替换结果,  -- 字符串替换
    LEN(Name) AS 字符串长度,  -- 获取长度
    UPPER(Name) AS 转大写,  -- 转大写
    LOWER(Name) AS 转小写;  -- 转小写
FROM Student;

2. 日期函数

sql 复制代码
SELECT 
    GETDATE() AS 当前时间,  -- 含日期+时间(常用)
    SYSDATETIME() AS 高精度时间,  -- 比GETDATE()精度高
    FORMAT(GETDATE(), 'yyyy-MM-dd HH:mm:ss') AS 格式化时间,  -- 自定义格式
    DATEADD(DAY, 7, GETDATE()) AS 7天后,  -- 日期加减(DAY可换MONTH/YEAR/HOUR)
    DATEDIFF(DAY, '2026-01-01', GETDATE()) AS 天数差,  -- 计算两个日期的差值
    YEAR(GETDATE()) AS 年份,  -- 提取年份
    MONTH(GETDATE()) AS 月份,  -- 提取月份
    DAY(GETDATE()) AS 日期;  -- 提取日期

3. 数值函数

sql 复制代码
SELECT 
    ROUND(89.63, 1) AS 四舍五入,  -- 保留1位小数
    FLOOR(89.9) AS 向下取整,  -- 结果89
    CEILING(89.1) AS 向上取整,  -- 结果90
    ABS(-89) AS 绝对值,  -- 结果89
    SQRT(16) AS 平方根;  -- 结果4
FROM Score;

八、索引:给查询装「加速器」(进阶核心)

1. 什么是索引(小白版)

索引就像书籍的目录

  • 无索引:查询时逐行扫描全表(翻遍整本书),数据量越大越慢;
  • 有索引:通过索引直接定位数据位置(按目录找页码),查询速度提升百倍。

2. 索引的分类(常用2种)

索引类型 核心特点 数量限制 适用场景
聚集索引(Clustered) 数据物理存储顺序与索引顺序一致,主键默认创建 表中仅1个 主键列(如Id)
非聚集索引(Nonclustered) 索引单独存储,记录指向数据行的指针 表中最多999个 WHERE条件、JOIN关联、ORDER BY列

3. 索引的创建/删除/查看

sql 复制代码
-- 1. 创建非聚集索引(默认NONCLUSTERED,可省略)
-- 格式1:单列索引
CREATE [NONCLUSTERED] INDEX 索引名
ON 表名 (列名 [ASC/DESC]);

-- 格式2:联合索引(多列,按查询频率排序)
CREATE INDEX 索引名
ON 表名 (列名1, 列名2);

-- 格式3:唯一索引(保证列值无重复,比普通索引查询更快)
CREATE UNIQUE INDEX 索引名
ON 表名 (列名);

-- 示例1:给Score表的StudentId+Subject建联合索引(开发高频)
CREATE INDEX IX_Score_StudentId_Subject
ON Score (StudentId, Subject);

-- 示例2:给Student表的IdCard建唯一索引(身份证号唯一)
CREATE UNIQUE INDEX IX_Student_IdCard
ON Student (IdCard);

-- 2. 删除索引
DROP INDEX 索引名 ON 表名;
DROP INDEX IX_Score_StudentId_Subject ON Score;

-- 3. 查看表的所有索引(系统存储过程)
EXEC sp_helpindex 'Student';

4. 索引使用「黄金法则」(小白必看,避坑关键)

该建索引的场景

  1. 频繁作为WHERE条件的列(如用户ID、订单号);
  2. 用于JOIN关联的列(如StudentId、ClassId);
  3. 用于ORDER BY/GROUP BY的列;
  4. 数据量超1000行的表(小表建索引无意义)。

不该建索引的场景

  1. 数据量极少的表(如配置表,几十行);
  2. 频繁插入/更新/删除的列(如日志表的创建时间,维护索引耗时);
  3. 重复值极高的列(如性别列,只有男/女,索引失效);
  4. 很少被查询的列。

九、事务(TRANSACTION):保证数据一致性

1. 什么是事务

保证多步数据库操作原子性 :要么全部成功 ,要么全部失败,适用于转账、订单创建等需要多步操作的场景(比如转账:扣减A账户→增加B账户,两步必须同时成功)。

2. 事务的核心属性(ACID)

  • 原子性(Atomic):操作要么全做,要么全不做;
  • 一致性(Consistent):操作前后数据总量不变(如转账总金额不变);
  • 隔离性(Isolated):多个事务互不干扰;
  • 持久性(Durable):事务提交后,数据永久保存。

3. 事务实战语法(TRY/CATCH版,开发推荐)

sql 复制代码
BEGIN TRANSACTION;  -- 开始事务
BEGIN TRY
    -- 执行多步操作(示例:转账,扣减ID1,增加ID2)
    UPDATE Account SET Balance = Balance - 100 WHERE Id = 1;
    UPDATE Account SET Balance = Balance + 100 WHERE Id = 2;
    
    COMMIT TRANSACTION;  -- 提交事务:所有操作生效
    PRINT '操作成功,事务已提交';
END TRY
BEGIN CATCH
    ROLLBACK TRANSACTION;  -- 回滚事务:撤销所有操作
    PRINT '操作失败,事务已回滚';
    -- 可选:打印错误信息
    PRINT '错误信息:' + ERROR_MESSAGE();
END CATCH;

十、存储过程:封装SQL逻辑(可重复调用)

1. 什么是存储过程

一段常用的SQL逻辑 封装成一个「函数」,可通过调用名 重复执行,支持参数传入/返回,提升开发效率和代码复用性,是数据库开发的核心知识点。

2. 存储过程的创建/调用/删除

sql 复制代码
-- 1. 创建存储过程(带输入参数)
CREATE PROCEDURE 存储过程名
    @参数1 数据类型,  -- 输入参数
    @参数2 数据类型 = 默认值  -- 带默认值的参数
AS
BEGIN
    SET NOCOUNT ON;  -- 关闭「受影响的行数」提示,可选
    -- 封装的SQL逻辑
    SELECT * FROM Student WHERE Age BETWEEN @参数1 AND @参数2;
END;

-- 示例:创建查询指定年龄范围学生的存储过程
CREATE PROCEDURE GetStudentByAge
    @MinAge INT = 18,  -- 默认最小年龄18
    @MaxAge INT = 30   -- 默认最大年龄30
AS
BEGIN
    SET NOCOUNT ON;
    SELECT Id, Name, Age, Score FROM Student WHERE Age BETWEEN @MinAge AND @MaxAge;
END;

-- 2. 调用存储过程
-- 方式1:按参数顺序调用
EXEC GetStudentByAge 18, 25;
-- 方式2:按参数名调用(推荐,参数顺序变更不影响)
EXEC GetStudentByAge @MinAge = 18, @MaxAge = 25;
-- 方式3:使用默认参数(只传部分)
EXEC GetStudentByAge @MaxAge = 22;

-- 3. 修改存储过程
ALTER PROCEDURE GetStudentByAge
    @MinAge INT = 18,
    @MaxAge INT = 30
AS
BEGIN
    SET NOCOUNT ON;
    -- 新增筛选:及格学生
    SELECT Id, Name, Age, Score FROM Student WHERE Age BETWEEN @MinAge AND @MaxAge AND Score >= 60;
END;

-- 4. 删除存储过程
DROP PROCEDURE [IF EXISTS] 存储过程名;
DROP PROCEDURE IF EXISTS GetStudentByAge;

十一、核心总结(小白速记)

1. 基础必掌握

  • 查:SELECT + WHERE + ORDER BY + TOP
  • 改:INSERT/UPDATE/DELETE(UPDATE/DELETE必加WHERE);
  • 建表:CREATE TABLE + 常用约束(主键、非空、默认值、外键)。

2. 进阶必掌握

  • 多表联查:LEFT JOIN(开发最高频)+ 3表联查逻辑;
  • 统计:聚合函数 + GROUP BY + HAVING(区分WHERE和HAVING的筛选时机);
  • 优化:索引(联合索引+唯一索引)+ 事务(保证数据一致性)。

3. 开发必掌握

  • 复用:存储过程(封装常用逻辑,带参数);
  • 函数:字符串/日期/数值内置函数(提升开发效率);
  • 子查询:嵌套查询(分步解决复杂业务问题)。

4. 避坑关键

  1. UPDATE/DELETE不加WHERE会操作全表,开发前可先加SELECT验证条件;
  2. 索引不是越多越好,频繁增删的表少建索引;
  3. 多表联查优先用LEFT JOIN,避免笛卡尔积(无关联条件导致数据爆炸);
  4. 大表查询避免用SELECT *,指定所需列减少IO操作。
相关推荐
资深web全栈开发2 小时前
PostgreSQL枚举还是字符串:ENUM vs VARCHAR + CHECK 的权衡
数据库·postgresql
凯子坚持 c2 小时前
C++基于微服务脚手架的视频点播系统---客户端(4)
数据库·c++·微服务
OceanBase数据库官方博客2 小时前
OceanBase场景解码系列三|OB Cloud 如何稳定支撑中企出海实现数 10 倍的高速增长?
数据库·oceanbase·分布式数据库
m0_561359672 小时前
使用Python处理计算机图形学(PIL/Pillow)
jvm·数据库·python
山岚的运维笔记2 小时前
SQL Server笔记 -- 第14章:CASE语句
数据库·笔记·sql·microsoft·sqlserver
Data_Journal2 小时前
如何使用 Python 解析 JSON 数据
大数据·开发语言·前端·数据库·人工智能·php
ASS-ASH2 小时前
AI时代之向量数据库概览
数据库·人工智能·python·llm·embedding·向量数据库·vlm
xixixi777773 小时前
互联网和数据分析中的核心指标 DAU (日活跃用户数)
大数据·网络·数据库·数据·dau·mau·留存率
范纹杉想快点毕业3 小时前
状态机设计与嵌入式系统开发完整指南从面向过程到面向对象,从理论到实践的全面解析
linux·服务器·数据库·c++·算法·mongodb·mfc