SQL Server 学习笔记(详细整理版)
涵盖数据库基础概念、数据类型、五大约束、DDL 库表结构操作、DML 增删改查、多表 JOIN、分组聚合、分页、子查询、结果集合并附带练习案例与避坑要点一、数据库基础必学概念核心学习清单数据库、架构 (schema)、表、字段、数据类型、约束、视图、存储过程、函数、触发器、临时表、表变量。1. 常用重点数据类型分类类型说明与注意事项字符类型varchar(n)非 Unicode 字符串存中文容易乱码适合纯英文数字nvarchar(n)Unicode 类型中文优先使用n 代表最多字符数量char / nchar定长字符长度不足自动补空格一般很少使用数值类型int整型普通数字bigint长整型用于自增主键 Id数据量大时使用decimal(精度,小数位)定点小数金额、价格必须用这个避免精度丢失float浮点数存在精度误差禁止用于金额计算时间类型datetime旧版时间类型精度较低datetime2推荐使用时间范围更大、精度更高坑点总结存储中文字符字段一律选用nvarchar避免中文乱码2. 五大约束保证数据完整性防止脏数据约束作用对表中数据做限制从数据库层面拦截非法数据。缩写约束名称关键字作用说明PK主键约束PRIMARY KEY唯一标识一行数据不能为 NULL不能重复一张表仅能设置 1 个主键支持多个字段组成复合主键UK唯一约束UNIQUE字段值不能重复SQL Server 允许最多 1 行 NULL不能多条 NULL一张表可设置多个唯一约束FK外键约束FOREIGN KEY引用另一张表的主键保障关联数据一致性例订单表UserId必须在用户表中真实存在CHECK检查约束CHECK()限制字段取值范围例价格≥0、年龄 0DEFAULT默认值约束DEFAULT 值插入数据不填写该字段时自动填充预设值例IsDelete bit DEFAULT 0默认未删除示例 1创建用户表 UserInfoCREATE TABLE UserInfo ( Id bigint PRIMARY KEY IDENTITY(1,1), -- PK主键自增从1开始步长1 UserName nvarchar(50) NOT NULL, Phone nvarchar(11) UNIQUE, -- UK唯一约束手机号不能重复 Age int CHECK(Age0), -- CHECK约束年龄必须大于0 Balance decimal(18,2) DEFAULT 0, -- DEFAULT 默认值 IsDelete bit DEFAULT 0 )示例 2创建订单表 OrderInfo外键关联用户表CREATE TABLE OrderInfo( OrderId bigint PRIMARY KEY IDENTITY(1,1), UserId bigint, OrderMoney decimal(18,2), -- FK外键关联UserInfo的Id主键 FOREIGN KEY(UserId) REFERENCES UserInfo(Id) );课堂练习新建 Product 产品表 需求主键 Id、产品名称唯一、价格大于等于 0、默认库存 100CREATE TABLE Product( Id bigint PRIMARY KEY IDENTITY(1,1), ProductName nvarchar(50) UNIQUE, Price decimal(18,2) CHECK(Price0), Inventory int DEFAULT 100 );二、DDL 数据定义语言操作库、表结构不操作表内数据核心关键字CREATE创建、ALTER修改、DROP删除⚠️警告DROP直接销毁对象没有回收站生产环境谨慎执行1. 数据库操作CREATE DATABASE StudyDB; -- 创建数据库StudyDB USE StudyDB; -- 切换当前操作的数据库 DROP DATABASE StudyDB; -- 删除数据库练习任务创建数据库BlogDBUSE BlogDB;切换库新建 Article 文章表主键 Id标题 nvarchar阅读量 int 默认 0使用 ALTER 新增创建时间字段 datetime2CREATE DATABASE BlogDB; GO USE BlogDB; CREATE TABLE Article( Id bigint PRIMARY KEY IDENTITY(1,1), Title nvarchar(100) NOT NULL, ReadNum int DEFAULT 0 ); -- ALTER新增创建时间 ALTER TABLE Article ADD CreateTime datetime2 DEFAULT SYSDATETIME();2.ALTER 修改表结构-- 新增字段 ALTER TABLE UserInfo ADD Email nvarchar(100); -- 修改字段类型 ALTER TABLE UserInfo ALTER COLUMN Email nvarchar(200); -- 删除字段 ALTER TABLE UserInfo DROP COLUMN Email;3.DROP 删除表DROP TABLE UserInfo; -- 删除整张表表结构数据全部消失三、DML 数据操作语言重点操作表里的数据行关键字SELECT查询、INSERT新增、UPDATE修改、DELETE删除✅ SELECT 完整书写顺序牢记SELECT 字段列表 FROM 表 别名 JOIN 关联表 ON 关联条件 WHERE 行过滤条件 GROUP BY 分组字段 HAVING 分组后过滤 ORDER BY 排序字段 OFFSET ... FETCH NEXT 分页1. 多表连接 JOIN连接类型说明INNER JOIN内连接只返回两边表可以匹配上的数据相当于交集LEFT JOIN左连接左表所有数据全部保留右表匹配不到右表字段填充 NULLRIGHT JOIN右连接右表全部保留左表匹配不到为 NULLCROSS JOIN交叉连接笛卡尔积大部分业务场景不使用2.WHERE在分组之前过滤原始数据行❌不能使用聚合函数SUM、COUNT、MAX等3.GROUP BY 分组 聚合函数常用聚合函数SUM()求和、COUNT()计数、AVG()求平均值、MAX()最大值、MIN()最小值规则SELECT 后面写的普通非聚合字段需要放到 GROUP BY 中 如果分组字段是主键SQL Server 允许同表其他字段不写进 GROUP BY为了兼容多数据库建议全部写上COUNT 补充重点COUNT(字段)统计该字段不为 NULL 的行数左连接统计子表记录优先用这个NULL 不会计数COUNT(*)统计行数不管是否为 NULL左连接统计子表不要用会统计出来错误数据AS 别名WHERE过滤原始行HAVING过滤分组后的结果AS用来给列设置查询临时别名不会修改原表字段AS 可以省略ORDER BY可以识别别名GROUP BY、HAVING不能识别别名COUNT(o.OrderId) AS OrderCount --带AS COUNT(o.OrderId) OrderCount --省略AS效果一样分组统计完成之后对分组结果过滤✅可以写聚合函数这是和 WHERE 最大区别5.ORDER BY 排序ORDER BY CreateTime DESC; --DESC降序最新数据放最上面ASC升序(默认)6. 分页两种写法写法 1TOP简单取前 N 条SELECT TOP 10 * FROM UserInfo;写法 2OFFSET ... FETCH NEXTSQL Server2012 及以上推荐⚠️强制要求分页必须搭配ORDER BY否则分页结果错乱不稳定 计算公式OFFSET (页码-1)*每页条数--第1页取10条 SELECT * FROM UserInfo ORDER BY Id OFFSET 0 ROWS FETCH NEXT 10 ROWS ONLY;综合练习任务LEFT JOIN 分组 HAVING 排序 分页需求LEFT JOIN 关联用户表、订单表统计每个用户订单总数HAVING 筛选订单总数≥2 的用户ORDER BY 总金额降序OFFSET FETCH 取第 1 页5 条数据SELECT u.ID,u.UserName, COUNT(o.OrderId) OrderCount , SUM(o.OrderMoney) TotalMoney FROM UserInfo u LEFT JOIN OrderInfo o ON u.Ido.UserId GROUP BY u.Id,u.UserName HAVING COUNT(o.OrderId)2 ORDER BY TotalMoney DESC OFFSET 0 ROWS FETCH NEXT 5 ROWS ONLY;7. 子查询标量子查询返回单个值可以放在 SELECT、WHERE 后使用IN 子查询返回一组值WHERE Id IN (1,2,3)EXISTS判断子查询是否有返回数据找到匹配立刻停止性能优于 IN示例查询有订单的用户SELECT * FROM UserInfo u WHERE EXISTS (SELECT 1 FROM OrderInfo o WHERE o.UserId u.Id);8.UNION/ UNION ALL 合并结果集要求前后查询列数量、数据类型必须保持一致UNION合并结果并且自动去重性能差UNION ALL直接拼接结果不去重业务优先使用速度更快SELECT Id,UserName FROM UserInfo WHERE Id1 UNION ALL SELECT Id,UserName FROM UserInfo WHERE Id29.INSERT/ UPDATE / DELETE 增删改-- INSERT插入 INSERT INTO UserInfo(UserName,Age) VALUES(N张三,20); -- UPDATE修改 UPDATE UserInfo SET Age21 WHERE Id1; -- DELETE删除 DELETE FROM UserInfo WHERE Id1;⚠️生产重要提醒UPDATE和DELETE执行前先用 SELECT 验证 WHERE 条件 一旦忘记写 WHERE 条件会造成全表更新、全表删除重大事故。