| 运算符 | 含义 | 示例 | 结果 |
|---|---|---|---|
| + | 加法 | SELECT 10 + 5; | 15 |
| - | 减法 | SELECT 10 - 5; | 5 |
| * | 乘法 | SELECT 10 * 5; | 50 |
| / | 除法 | SELECT 10 / 5; | 2 |
| % | 取模(求余数) | SELECT 10 % 3; | 1 |
SQL 1)是用于管理关系数据库管理系统(RDBMS)的标准编程语言, 用来存储、查询、更新和管理数据,根据操作目的,SQL 语句通常分为以下四类
| 分类 | 全称 | 作用 | 常见关键字 |
| DQL | Data Query Language | 数据查询:从数据库中检索数据 | SELECT, FROM, WHERE, JOIN, GROUP BY |
| DML | Data Manipulation Language | 数据操作:对表中的数据进行增删改 | INSERT, UPDATE, DELETE |
| DDL | Data Definition Language | 数据定义:定义或修改数据库结构(表、索引等) | CREATE, ALTER, DROP, TRUNCATE |
| DCL | Data Control Language | 数据控制:管理权限和事务 | GRANT, REVOKE, COMMIT, ROLLBACK |
数字常量包括整数、小数以及浮点数 2)
字符串常量括在单引号内,包含字母和数字字符以及特殊字符,如 !,@,#,如果单引号的字符串包含一个嵌入的引号,可以使用两个的单引号表示嵌入的单引号
🚩 假设你要插入一条包含 It's 的数据: INSERT INTO messages (content) VALUES ('It''s a test');
在标准的 SQL 语法中,日期和时间常量通常遵循以下格式:
| 类别 | 符号常量 (标准 SQL) | 含义与说明 | 常见数据库方言/替代写法 |
|---|---|---|---|
| 空值与逻辑 | NULL | 数据缺失、未知,不可用 = 比较,必须用 IS NULL | 通用 |
| 空值与逻辑 | TRUE | 布尔真值 | MySQL 旧版视为 1;Oracle 无原生布尔,常用 1 或 'Y' |
| 空值与逻辑 | FALSE | 布尔假值 | MySQL 旧版视为 0;Oracle 常用 0 或 'N' |
| 日期与时间 | CURRENT_DATE | 当前系统日期 (无时间部分) | Oracle: TRUNC(SYSDATE) |
| 日期与时间 | CURRENT_DATE | 当前系统日期 (无时间部分) | MySQL: CURDATE() |
| 日期与时间 | CURRENT_DATE | 当前系统日期 (无时间部分) | SQL Server: CAST(GETDATE() AS DATE) |
| 日期与时间 | CURRENT_TIME | 当前系统时间 (无日期部分,含时区) | Oracle: 无直接对应,需 TO_CHAR(SYSDATE, 'HH24:MI:SS') |
| 日期与时间 | CURRENT_TIME | 当前系统时间 (无日期部分,含时区) | MySQL: CURTIME() |
| 日期与时间 | CURRENT_TIMESTAMP | 当前完整日期和时间 (含时区) | Oracle: SYSTIMESTAMP |
| 日期与时间 | CURRENT_TIMESTAMP | 当前完整日期和时间 (含时区) | MySQL: NOW() |
| 日期与时间 | CURRENT_TIMESTAMP | 当前完整日期和时间 (含时区) | SQL Server: SYSDATETIME() |
| 日期与时间 | LOCALTIMESTAMP | 当前本地日期和时间 (不含时区) | Oracle: SYSDATE |
| 日期与时间 | LOCALTIMESTAMP | 当前本地日期和时间 (不含时区) | MySQL: NOW() |
| 日期与时间 | LOCALTIMESTAMP | 当前本地日期和时间 (不含时区) | SQL Server: GETDATE() |
| 用户与环境 | CURRENT_USER | 当前会话的数据库用户名 | Oracle: USER |
| 用户与环境 | CURRENT_USER | 当前会话的数据库用户名 | MySQL: USER() |
| 用户与环境 | CURRENT_USER | 当前会话的数据库用户名 | SQL Server: SUSER_SNAME() |
| 用户与环境 | SESSION_USER | 会话初始连接用户 (通常与 CURRENT_USER 相同) | SQL Server: ORIGINAL_LOGIN() |
| 用户与环境 | SYSTEM_USER | 底层操作系统用户名 | SQL Server: SYSTEM_USER |
| 用户与环境 | SYSTEM_USER | 底层操作系统用户名 | Oracle/MySQL: 无直接标准对应 |
| 用户与环境 | CURRENT_SCHEMA | 当前默认的 Schema/数据库名 | MySQL: DATABASE() |
| 用户与环境 | CURRENT_SCHEMA | 当前默认的 Schema/数据库名 | SQL Server: SCHEMA_NAME() |
| 系统状态 | UNKNOWN | 三值逻辑中的“未知”状态 (NULL 参与比较时产生) | 极少直接使用,通常由 NULL 比较自动产生 |
在 SQL 中,变量用于在批处理、脚本或存储过程中临时存储数据值,是控制程序逻辑(如循环、条件判断)和处理中间结果的重要工具
在 SQL 中,局部变量和全局变量的核心区别在于作用域(可见范围)和生命周期,局部变量是由用户自己定义的,用于在特定的代码块或事务中临时存储数据
DECLARE @myCount INT; DECLARE myCount INT; DECLARE @myName NVARCHAR(50);SET @myName = '张三'; DECLARE @count INT, @maxAge INT;SELECT @count = 10, @maxAge = 60; 在 SQL Server 中,我们通常所说的“全局变量”实际上是由系统预定义和维护的系统函数。它们主要用于提供有关 SQL Server 系统配置、当前会话状态或上一条 SQL 语句执行结果的信息
🚩以下是整理好的 SQL Server 常用全局变量表格
| 分类 | 全局变量 (系统函数) | 含义与说明 |
|---|---|---|
| 系统与配置 | @@VERSION | 返回当前 SQL Server 的版本、处理器架构和操作系统信息 |
| 系统与配置 | @@SERVERNAME | 返回运行 SQL Server 的本地服务器名称 |
| 系统与配置 | @@LANGUAGE | 返回当前使用的语言名称 |
| 系统与配置 | @@MAX_CONNECTIONS | 返回 SQL Server 实例允许同时进行的最大用户连接数 |
| 语句执行状态 | @@ROWCOUNT | 返回受上一条 SQL 语句影响的行数(常用于判断操作是否成功) |
| 语句执行状态 | @@ERROR | 返回最后执行的 T-SQL 语句的错误号(成功返回 0,失败返回错误代码) |
| 语句执行状态 | @@IDENTITY | 返回当前会话中最后一次插入的标识值(自增 ID) |
| 事务与连接 | @@TRANCOUNT | 返回当前连接(会话)中打开的活动事务数 |
| 事务与连接 | @@SPID | 返回当前用户进程的服务器进程 ID |
| 性能与统计 | @@CONNECTIONS | 返回自 SQL Server 上次启动以来的登录或尝试登录的次数 |
| 性能与统计 | @@CPU_BUSY | 返回自 SQL Server 上次启动以来,CPU 用于执行 SQL Server 工作的微秒数 |
| 性能与统计 | @@IDLE | 返回自 SQL Server 上次启动以来,SQL Server 处于空闲状态的微秒数 |
| 性能与统计 | @@TOTAL_READ | 返回 SQL Server 执行的磁盘读取次数 |
| 性能与统计 | @@TOTAL_WRITE | 返回 SQL Server 执行的磁盘写入次数 |
不同数据库的特殊注释语法:MySQL:支持 # 作为单行注释
| 运算符 | 含义 | 示例 | 结果 |
|---|---|---|---|
| + | 加法 | SELECT 10 + 5; | 15 |
| - | 减法 | SELECT 10 - 5; | 5 |
| * | 乘法 | SELECT 10 * 5; | 50 |
| / | 除法 | SELECT 10 / 5; | 2 |
| % | 取模(求余数) | SELECT 10 % 3; | 1 |
在 SQL Server 中,赋值主要通过 SET 或 SELECT 语句结合 = 号来实现
DECLARE @myVar INT;
SET @myVar = 10; -- 使用 = 将 10 赋给 @myVar
从 SQL Server 2008 开始,引入了复合赋值运算符3)
SET @myVar += 5; 等价于 SET @myVar = @myVar + 5;
在 SQL Server 中,= 就是赋值;在 MySQL 的 SELECT 语句中,必须用 := 来赋值,= 只用来做比较
| 运算符 | 含义 | 示例 | 说明 |
|---|---|---|---|
| = | 等于 | WHERE age = 18 | 判断两个表达式是否相等 |
| <> 或 != | 不等于 | WHERE status != 'Active' | <> 是 ISO 标准,!= 也是广泛支持的非标准写法 |
| > | 大于 | WHERE price > 100 | 判断左侧表达式是否大于右侧 |
| < | 小于 | WHERE age < 60 | 判断左侧表达式是否小于右侧 |
| >= | 大于或等于 | WHERE score >= 90 | 判断左侧表达式是否大于或等于右侧 |
| ⇐ | 小于或等于 | WHERE age ⇐ 18 | 判断左侧表达式是否小于或等于右侧 |
| BETWEEN … AND … | 范围查询 | WHERE price BETWEEN 10 AND 20 | 包含边界值,等价于 >= 10 AND ⇐ 20 |
| IN (…) | 列表匹配 | WHERE status IN ('Active', 'Pending') | 判断值是否在给定的列表中(多选一) |
| LIKE | 模糊匹配 | WHERE name LIKE '%张%' | % 代表任意长度字符,_ 代表单个字符 |
| IS NULL | 判断为空 | WHERE email IS NULL | 判断字段是否为空值(不可用 = NULL) |
| IS NOT NULL | 判断非空 | WHERE phone IS NOT NULL | 判断字段是否不为空值(不可用 != NULL) |
| 运算符 | 含义 | 示例 | 说明 |
|---|---|---|---|
| AND | 逻辑与 | WHERE age > 18 AND status = 'Active' | 两个条件都为 TRUE 时,结果才为 TRUE |
| OR | 逻辑或 | WHERE city = 'Beijing' OR city = 'Shanghai' | 只要有一个条件为 TRUE,结果即为 TRUE |
| NOT | 逻辑非 | WHERE NOT status = 'Inactive' | 对条件结果取反,TRUE 变 FALSE,FALSE 变 TRUE |
| && | 逻辑与 (非标准) | WHERE age > 18 && status = 'Active' | 部分数据库支持,建议优先使用 AND |
| || | 逻辑或 (非标准) | WHERE city = 'Beijing' || city = 'Shanghai' | 部分数据库支持,建议优先使用 OR |
| ! | 逻辑非 (非标准) | WHERE !status = 'Inactive' | 部分数据库支持,建议优先使用 NOT |
连接运算符 + 主要用于将两个或多个数据项(如字符串、变量、表达式或常量)合并为一个整体,其核心作用是在数据处理和输出格式化中实现内容的无缝拼接
| 关键字 | 核心作用 | 常用场景与示例 |
|---|---|---|
| ALL | 必须满足子查询返回的所有条件 | WHERE Salary > ALL (SELECT Salary FROM SalesDept) |
| SOME | 满足子查询返回的任意一个条件即可(与 ANY 等价) | WHERE Salary > SOME (SELECT Salary FROM SalesDept) |
| ANY | 满足子查询返回的任意一个条件即可(与 SOME 等价) | WHERE Salary > ANY (SELECT Salary FROM SalesDept) |
| EXISTS | 检查子查询是否至少有一行结果(返回 TRUE/FALSE) | WHERE EXISTS (SELECT 1 FROM Orders WHERE CustomerID = c.ID) |
| AS | 起别名、定义查询结构或指定转换类型 | SELECT Name AS 姓名、WITH CTE AS (…)、CAST(123 AS VARCHAR) |
| 通配符 | 含义 | 示例 | 说明 |
|---|---|---|---|
| % | 代表任意长度的任意字符 | WHERE name LIKE '%张%' | 匹配包含“张”的任意字符串,如“张三”、“小张”、“老张” |
| _ | 代表任意单个字符 | WHERE name LIKE '_三' | 匹配以任意单个字符开头且以“三”结尾的名字,如“张三”、“李三” |
| [] | 字符列表中的任一单个字符 | WHERE name LIKE '[张李王]三' | 匹配“张三”、“李三”或“王三”(SQL Server 支持) |
| [^] | 不在字符列表中的任一单个字符 | WHERE name LIKE '[^张李]三' | 匹配不以“张”或“李”开头且以“三”结尾的名字(SQL Server 支持) |
| [-] | 字符范围内的任一单个字符 | WHERE code LIKE '[A-C]001' | 匹配“A001”、“B001”或“C001”(SQL Server 支持) |
BEGIN…END 是流程控制语言的关键字,主要用于将多条 SQL 语句组合为一个逻辑代码块,它的作用类似于 C、Java 等编程语言中的大括号 {}
IF (@@ERROR <> 0) BEGIN SET @ErrorSaveVariable = @@ERROR; PRINT 'Error encountered, ' + CAST(@ErrorSaveVariable AS VARCHAR(10)); END -- 如果不加 BEGIN...END,当 @@ERROR <> 0 时,只有 SET 语句会被执行,而 PRINT 语句无论条件是否成立都会执行
IF<条件表达式> {命令行|程序块}
IF<条件表达式> {命令行1|程序块1} ELSE {命令行2|程序块2}
在 SQL 中,CASE 表达式用于实现条件逻辑,它允许你根据不同的条件返回不同的值。你可以把它理解为 SQL 中的 IF…ELSE IF…ELSE 逻辑
CASE input_expression WHEN when_expression_1 THEN result_1 WHEN when_expression_2 THEN result_2 ... [ELSE else_result] END
🚩
SELECT ProductName,
CASE CategoryID
WHEN 1 THEN '电子产品'
WHEN 2 THEN '服装'
WHEN 3 THEN '食品'
ELSE '其他类别'
END AS CategoryName
FROM Products;
用于评估多个布尔表达式,返回第一个计算结果为 TRUE 的对应值。它比简单 CASE 更灵活,支持范围判断和复杂的逻辑条件
CASE WHEN boolean_condition_1 THEN result_1 WHEN boolean_condition_2 THEN result_2 ... [ELSE else_result] END
🚩
SELECT ProductName, Price,
CASE
WHEN Price > 1000 THEN '昂贵'
WHEN Price BETWEEN 100 AND 1000 THEN '适中'
WHEN Price < 100 THEN '便宜'
ELSE '未定价'
END AS PriceLevel
FROM Products;
WHILE<条件表达式> BEGIN <命令行|程序块> END
WHILE<条件表达式> BEGIN <命令行|程序块> [BREAK] [CONTINUE] [命令行|程序块] END
在 SQL 中,RETURN 是一个非常关键的控制流关键字,它的主要作用是无条件地立即终止当前的执行流程,并退出当前的程序单元
| 状态码 | 官方建议含义 | 状态码 | 官方建议含义 |
|---|---|---|---|
| -1 | 找不到对象或权限不足 | -2 | 发生语法错误 |
| -3 | 超时(Timeout) | -4 | 违反权限规则 |
| -5 | 发生死锁(Deadlock) | -6 | 发生致命错误 |
| -7 | 发生数据类型转换错误 | -8 | 字符串被截断 |
| -9 | 无效的列名 | -10 | 无效的表名 |
| -11 | 无效的数据库名 | -12 | 无效的参数 |
| -13 | 违反约束 | -14 | 违反触发器 |
| -99 到 -999 | 系统保留的错误代码范围 | F | 程序执行成功 |
在 SQL Server 中,GOTO 是一种流程控制语句,它的主要作用是改变代码的执行顺序,使程序无条件跳转到指定的“标签(Label)”处继续执行
-- 1. 定义标签(标签名后必须加冒号) label_name: -- 2. 改变执行流程(跳转到指定标签) GOTO label_name;
WAITFOR 是 SQL Server中用于控制执行流程的命令。它的主要作用是暂停或延迟批处理、存储过程或事务的执行,直到指定的时间间隔过去,或者到达某个特定的时间点
下面的代码会让程序暂停 10 秒钟后再执行程序
WAITFOR DELAY '00:00:10';
下面的代码会让程序一直等待,直到晚上 10 点 20 分才开始执行程序
WAITFOR TIME '22:20';
DBCC(Database Console Commands,数据库控制台命令)是 SQL Server 中一组非常强大的系统级指令,它主要用于数据库的维护、验证、信息收集等任务。
🚩 为了让你更直观地了解 DBCC 的常用功能,这里列举几个最核心的命令
| 命令名称 | 主要功能 |
| DBCC CHECKDB | 检查指定数据库中所有对象的分配和结构完整性,是最常用的诊断命令 |
| DBCC SHRINKDATABASE | 尝试收缩指定数据库的所有数据和日志文件的大小 |
| DBCC SHRINKFILE | 收缩当前数据库中指定数据或日志文件的大小 |
| DBCC TRACEON | 启用指定的跟踪标志,常用于开启死锁诊断或改变查询优化器行为 |
| DBCC HELP | 显示指定 DBCC 语句的语法帮助信息 |
在 SQL Server 中,CHECKPOINT 是一个至关重要的机制,它的主要作用是将内存中已修改但尚未写入磁盘的数据页 4)强制刷新到磁盘,并在事务日志中记录
简单来说,它的核心目的有两个:
在 SQL Server 中,DECLARE 是用来定义(声明)局部变量或表变量的关键字
基本语法: DECLARE @变量名 数据类型;
🚩 常用示例
-- 1. 声明一个整数变量 DECLARE @EmployeeID INT; -- 2. 声明一个字符串变量(指定最大长度) DECLARE @EmployeeName NVARCHAR(50); -- 3. 声明的同时直接赋值 DECLARE @CurrentDate DATE = GETDATE(); -- 4. 声明多个变量(用逗号隔开) DECLARE @Age INT = 25, @Salary DECIMAL(10,2) = 5000.00;
基本语法: DECLARE @表变量名 TABLE ( 列名1 数据类型,列名2 数据类型,...);
🚩 实例
-- 声明一个表变量,用来暂存部门信息 DECLARE @TempDepartments TABLE ( DeptID INT PRIMARY KEY, DeptName NVARCHAR(50) ); -- 往表变量里插入数据 INSERT INTO @TempDepartments (DeptID, DeptName) VALUES (1, 'IT部'), (2, '人事部'); -- 像查询普通表一样查询它 SELECT * FROM @TempDepartments WHERE DeptID = 1;
在 SQL Server 中,PRINT 是一个非常基础且常用的命令,主要用于向客户端输出文本消息
基本语法: PRINT '要输出的文本内容'; 或者 PRINT @变量名;
在 SQL Server 中,RAISERROR 是一个用于主动抛出自定义错误或警告信息的强大命令
基本语法: RAISERROR ( '错误消息文本' , 严重级别 , 状态 )
在 SQL Server 中,READTEXT 是一个专门用于从 text、ntext 或 image 数据类型的列中,读取部分或全部数据的命令
它允许你指定从哪个位置(偏移量)开始读取,以及读取多少个字节或字符
基本语法: READTEXT { table.column text_ptr offset size } [ HOLDLOCK ]
在 SQL Server 中,BACKUP 是数据库管理员(DBA)工具,它的主要作用是为数据库、事务日志或文件创建一个安全副本,以便在发生数据损坏、误操作或硬件故障时进行恢复
SQL Server 支持三种不同维度的备份策略,通常会组合使用
🚩常用语法与示例
-- 将 MyDatabase 完整备份到指定的磁盘文件 BACKUP DATABASE [MyDatabase] TO DISK = 'D:\Backup\MyDatabase_Full.bak' WITH FORMAT, -- 覆盖媒体集,开始新的备份集 COMPRESSION, -- 启用备份压缩,节省磁盘空间 STATS = 10; -- 每完成 10% 在消息栏输出一次进度
BACKUP DATABASE [MyDatabase] TO DISK = 'D:\Backup\MyDatabase_Diff.bak' WITH DIFFERENTIAL, -- 关键参数:指定为差异备份 COMPRESSION, STATS = 10;
BACKUP LOG [MyDatabase] -- 注意这里是 BACKUP LOG TO DISK = 'D:\Backup\MyDatabase_Log.trn' WITH COMPRESSION, STATS = 10;
在 SQL Server 中,RESTORE 命令它的主要作用就是从备份文件(.bak 或 .trn)中读取数据,并将数据库恢复到指定的状态
简单来说,BACKUP 负责“存档”,而 RESTORE 负责“读档,RESTORE 命令非常灵活,根据不同的需求,主要有以下几种用法
-- 从磁盘文件还原整个数据库 RESTORE DATABASE [MyDatabase] FROM DISK = 'D:\Backup\MyDatabase_Full.bak' WITH RECOVERY; -- 默认就是 RECOVERY,让数据库立即可用
--还原事务日志备份 RESTORE LOG [MyDatabase] FROM DISK = 'D:\Backup\MyDatabase_Log.trn' WITH RECOVERY;
在 SQL Server 中,SELECT 不仅仅是用来“查”数据的,它还是给变量赋值、甚至快速创建表的主力军
DECLARE @Name NVARCHAR(50), @Age INT; -- 一条语句搞定两个变量的赋值 SELECT @Name = 'Admin', @Age = 25; -- SELECT 从查询中赋值 DECLARE @EmployeeName NVARCHAR(50); -- 将查询到的第一行数据的 Name 列的值赋给变量 SELECT @EmployeeName = Name FROM Employees WHERE ID = 1;
在 SQL Server 中,SET 是一个极其重要的关键字,它主要有两大核心身份:一是作为给变量赋值的专用命令,二是作为修改当前会话环境的配置开关
基本语法: SET @变量名 = 值;
🚩 实例
DECLARE @Name NVARCHAR(50); DECLARE @Count INT; -- 给字符串变量赋值 SET @Name = 'Admin'; -- 给数字变量赋值 SET @Count = 100; -- 支持复合赋值运算符(类似 C# 或 Java) SET @Count += 10; -- 等同于 @Count = @Count + 10
除了赋值,SET 还能用来控制当前数据库连接(会话)的各种行为,这些设置会影响后续 SQL 语句的执行方式
🚩 常用场景示例
SET NOCOUNT ON : 默认情况下,每次执行 INSERT、UPDATE 或 DELETE 后,SQL Server 都会返回一条类似“(1 行受影响)”的消息,加上这句可以屏蔽这些消息,显著提升性能
SET IDENTITY_INSERT ON : 当表的主键是自动增长的(Identity)时,默认是不允许手动插入 ID 的,用这个命令可以临时开启手动插入权限
SET STATISTICS IO ON / TIME ON : 在调优 SQL 语句时非常有用,它会输出查询消耗了多少次磁盘读取以及执行耗时
SET DATEFIRST : 控制 DATEPART 函数中“星期几”的计算起点 6)
在 SQL Server 中,SHUTDOWN 是一个用于立即停止 SQL Server 数据库引擎服务的 Transact-SQL 命令
基本语法: SHUTDOWN [ WITH NOWAIT ]
在 SQL Server 中,WRITETEXT 是一个专门用于对 text、ntext 或 image 数据类型的列进行交互式更新的命令,它的核心作用是完全覆盖目标列中现有的所有数据
和 READTEXT 一样,WRITETEXT 也是一个即将被废弃的功能,微软官方明确建议,在新的开发工作中避免使用它
并推荐改用大值数据类型(如 VARCHAR(MAX))配合 UPDATE 语句的 .WRITE 子句
在 SQL Server 中,USE 是一个非常基础且高频使用的命令,它的主要作用是切换当前会话的数据库上下文
基本语法: USE 数据库名;
在 SQL Server 中,聚合函数是对一组值执行计算并返回单个值的函数,通常与 GROUP BY 子句配合使用,用于对数据进行分组汇总
🚩 假设我们有一张 Employees(员工表),包含 Department(部门)、Salary(薪资)和 Age(年龄)等字段
-- 统计公司总人数 SELECT COUNT(*) AS TotalEmployees FROM Employees; -- 统计“销售部”的人数 SELECT COUNT(*) FROM Employees WHERE Department = '销售部'; -- 注意:COUNT(列名) 会忽略该列值为 NULL 的行 SELECT COUNT(Salary) FROM Employees;
计算全公司的薪资总支出: SELECT SUM(Salary) AS TotalSalary FROM Employees;
计算全公司的平均年龄: SELECT AVG(Age) AS AverageAge FROM Employees;
找出公司里的最高薪资和最低薪资: SELECT MAX(Salary) AS HighestSalary, MIN(Salary) AS LowestSalary FROM Employees;
查询所有不重复的员工名字: SELECT DISTINCT Name FROM Employees;
限制查询结果显示的行数: SELECT TOP 5 Name FROM Employees;
| 函数名称 | 作用说明 | 示例代码 | 示例结果 |
|---|---|---|---|
| ABS() | 求绝对值 | SELECT ABS(-15) | 15 |
| ROUND() | 四舍五入到指定小数位 | SELECT ROUND(123.456, 2) | 123.460 |
| FLOOR() | 向下取整(去尾法) | SELECT FLOOR(123.99) | 123 |
| CEILING() | 向上取整(进一法) | SELECT CEILING(123.01) | 124 |
| POWER() | 求幂(次方) | SELECT POWER(2, 3) | 8 |
| SQRT() | 求平方根 | SELECT SQRT(16) | 4 |
| SIGN() | 判断正负(正1,负-1,0为0) | SELECT SIGN(-50) | -1 |
| RAND() | 生成 0 到 1 之间的随机浮点数 | SELECT RAND() | 0.123… |
| LOG() | 求自然对数(以 e 为底) | SELECT LOG(10) | 2.302… |
| EXP() | 求指数(e 的指定次幂) | SELECT EXP(2) | 7.389… |
| SIN() | 求正弦值(弧度) | SELECT SIN(1.57) | 1.000… |
| COS() | 求余弦值(弧度) | SELECT COS(0) | 1 |
| 函数名称 | 作用说明 | 示例代码 | 示例结果 |
|---|---|---|---|
| ASCII() | 返回字符最左侧的 ASCII 码值 | SELECT ASCII('A') | 65 |
| LEN() | 返回字符串的字符数 | SELECT LEN('SQL') | 3 |
| UPPER() | 将字符串转换为大写 | SELECT UPPER('sql') | SQL |
| LOWER() | 将字符串转换为小写 | SELECT LOWER('SQL') | sql |
| LTRIM() | 去除字符串左侧的空格 | SELECT LTRIM(' Hello') | Hello |
| RTRIM() | 去除字符串右侧的空格 | SELECT RTRIM('Hello ') | Hello |
| REPLACE() | 替换字符串中的指定字符 | SELECT REPLACE('abc', 'b', 'x') | axc |
| SUBSTRING() | 截取字符串的一部分 | SELECT SUBSTRING('Hello', 2, 3) | ell |
| CONCAT() | 拼接两个或多个字符串 | SELECT CONCAT('A', 'B') | AB |
| REVERSE() | 反转字符串 | SELECT REVERSE('abc') | cba |
| 函数名称 | 作用说明 | 示例代码 | 示例结果 |
|---|---|---|---|
| GETDATE() | 获取当前系统日期和时间 | SELECT GETDATE() | 2026-07-15 15:52:00 |
| YEAR() | 返回日期的年份 | SELECT YEAR('2026-07-15') | 2026 |
| MONTH() | 返回日期的月份 | SELECT MONTH('2026-07-15') | 7 |
| DAY() | 返回日期的天数 | SELECT DAY('2026-07-15') | 15 |
| DATEADD() | 在日期上增加指定的时间间隔 | SELECT DATEADD(day, 1, '2026-07-15') | 2026-07-16 |
| DATEDIFF() | 计算两个日期之间的差值 | SELECT DATEDIFF(day, '2026-07-01', '2026-07-15') | 14 |
| 函数名称 | 作用说明 | 示例代码 | 示例结果 |
|---|---|---|---|
| CAST() | 数据类型转换(ANSI标准) | SELECT CAST(123 AS VARCHAR) | '123' |
| CONVERT() | 数据类型转换(SQL Server特有) | SELECT CONVERT(VARCHAR, GETDATE(), 112) | 20260715 |
| ISNULL() | 如果表达式为 NULL,则返回指定值 | SELECT ISNULL(NULL, '默认值') | 默认值 |
| 函数名称 | 作用说明 | 示例代码 | 示例结果 |
|---|---|---|---|
| DB_ID() | 返回数据库的 ID 号 | SELECT DB_ID() | 5 |
| DB_NAME() | 返回数据库的名称 | SELECT DB_NAME() | MyDatabase |
| OBJECT_ID() | 返回数据库对象的 ID 号 | SELECT OBJECT_ID('Employees') | 123456789 |
| OBJECT_NAME() | 返回数据库对象的名称 | SELECT OBJECT_NAME(123456789) | Employees |
一个完整的 SELECT 语句包含多个子句(参数),它们必须按照固定的顺序书写,完整语法结构如下
SELECT [ ALL | DISTINCT ] [ TOP ( expression ) [ PERCENT ] [ WITH TIES ] ] 列名1, 列名2 INTO 新表名 FROM 表名 WHERE 筛选条件 GROUP BY 分组列 HAVING 分组后的筛选条件 ORDER BY 排序列 [ ASC | DESC ]
在 SQL Server 中,WITH 子句用于定义公用表表达式(Common Table Expression,简称 CTE)
你可以把 CTE 理解为一个“临时的、命名的结果集”,它就像你在查询过程中临时搭建的一个“虚拟视图”,只在当前这一条查询语句中有效
基本语法
WITH CTE名称 (列名1, 列名2, ...) AS ( -- 这里写定义 CTE 的查询语句 SELECT 列名1, 列名2 FROM 表名 WHERE 条件 ) -- 紧接着必须是一条引用该 CTE 的语句(SELECT, INSERT, UPDATE, DELETE 等) SELECT * FROM CTE名称;
🚩 常用场景与代码示例
-- 定义一个 CTE 来计算每个部门的平均薪资 WITH DeptAvgSalary AS ( SELECT Department, AVG(Salary) AS AvgSalary FROM Employees GROUP BY Department ) -- 在主查询中直接引用这个 CTE SELECT * FROM DeptAvgSalary WHERE AvgSalary > 10000;
WITH -- 第一个 CTE:筛选出在职员工 ActiveEmployees AS ( SELECT EmployeeID, Name, Department FROM Employees WHERE Status = 'Active' ), -- 第二个 CTE:基于第一个 CTE 统计各部门人数 DeptCount AS ( SELECT Department, COUNT(*) AS TotalCount FROM ActiveEmployees GROUP BY Department ) -- 主查询:引用第二个 CTE SELECT * FROM DeptCount ORDER BY TotalCount DESC;
-- 查询员工及其上级领导的层级关系 WITH EmployeeHierarchy AS ( -- 锚点成员:找到没有上级的老板(顶层) SELECT EmployeeID, Name, ManagerID, 0 AS Level FROM Employees WHERE ManagerID IS NULL UNION ALL -- 递归成员:找到老板手下的员工,并不断向下递归 SELECT e.EmployeeID, e.Name, e.ManagerID, eh.Level + 1 FROM Employees e INNER JOIN EmployeeHierarchy eh ON e.ManagerID = eh.EmployeeID ) SELECT * FROM EmployeeHierarchy;
如果把一条完整的 SQL 查询比作“去仓库取货”,那么:FROM 决定了你要去哪个仓库(数据源),SELECT 决定了你要从仓库里拿哪些具体的商品(数据列)
SELECT * FROM Employees;
SELECT e.Name, d.DepartmentName FROM Employees e INNER JOIN Departments d ON e.DeptID = d.ID;
SELECT Name, Salary FROM ( SELECT Name, Salary FROM Employees WHERE Department = '销售部' ) AS TempTable; -- 必须给子查询起别名
WITH HighSalary AS ( SELECT Name, Salary FROM Employees WHERE Salary > 20000 ) SELECT * FROM HighSalary;
在 SQL Server 中,INTO 子句通常配合 SELECT 语句使用(即 SELECT … INTO),它的核心作用是将查询结果直接存入一张全新的表中
基本语法: SELECT 列名1, 列名2, ...INTO 新表名 FROM 源表名 WHERE 筛选条件;
在 SQL Server 中,WHERE 子句是数据查询语句中的“过滤器”,它紧跟在 FROM 子句之后,用于指定搜索条件,从而筛选出满足特定条件的数据行
基本语法: SELECT 列名1, 列名2, ...FROM 表名 WHERE 筛选条件
在 SQL Server 中,GROUP BY 子句是数据分析的“分类整理大师”,它的核心作用是将查询结果集中的数据,按照一个或多个指定的列进行分组
基本语法: SELECT 分组列1, 分组列2, 聚合函数(列名) FROM 表名 WHERE 筛选条件 GROUP BY 分组列1, 分组列2;
🚩常用场景与代码示例
-- 统计每个部门的员工总数 SELECT Department, COUNT(*) AS EmployeeCount FROM Employees GROUP BY Department;
-- 统计每个部门中,不同职位的员工人数 SELECT Department, JobTitle, COUNT(*) AS JobCount FROM Employees GROUP BY Department, JobTitle;
-- 按年份统计每年的订单总金额 SELECT YEAR(OrderDate) AS OrderYear, SUM(TotalAmount) AS YearlyTotal FROM Orders GROUP BY YEAR(OrderDate);
在 SQL Server 中,HAVING 子句是专门用来对 GROUP BY 分组后的结果进行筛选的
基本语法: SELECT 分组列, 聚合函数(列名) FROM 表名 GROUP BY 分组列 HAVING 聚合函数的筛选条件;
🚩 常用场景与代码示例
-- 统计每个部门的人数,并只保留人数大于 10 的部门 SELECT Department, COUNT(*) AS EmployeeCount FROM Employees GROUP BY Department HAVING COUNT(*) > 10;
-- 找出平均薪资大于 15000,且总薪资支出超过 200000 的部门 SELECT Department, AVG(Salary) AS AvgSalary, SUM(Salary) AS TotalSalary FROM Employees GROUP BY Department HAVING AVG(Salary) > 15000 AND SUM(Salary) > 200000;
-- 筛选出部门名称以“销售”开头的分组 SELECT Department, COUNT(*) FROM Employees GROUP BY Department HAVING Department LIKE '销售%';
在 SQL Server 中,ORDER BY 子句是查询语句的“排版师”,它的核心作用是对最终查询出来的结果集进行排序
基本语法: SELECT 列名1, 列名2 FROM 表名 ORDER BY 排序列 [ASC | DESC];
ASC:升序(从小到大,A-Z,旧到新),这是默认选项,不写也代表升序。DESC:降序(从大到小,Z-A,新到旧)
🚩 常用场景与代码示例
-- 按年龄从小到大排序 SELECT Name, Age FROM Employees ORDER BY Age; -- 按薪资从高到低排序(显式指定 DESC) SELECT Name, Salary FROM Employees ORDER BY Salary DESC;
-- 先按部门名称升序排列;如果部门相同,再按薪资降序排列 SELECT Name, Department, Salary FROM Employees ORDER BY Department ASC, Salary DESC;
-- 按计算出的年薪进行降序排列 SELECT Name, Salary * 12 AS YearlySalary FROM Employees ORDER BY YearlySalary DESC;
你可以用 SELECT 后面列的顺序号(从 1 开始)来代替列名
-- 等同于 ORDER BY Name SELECT Name, Department FROM Employees ORDER BY 1;
在 SQL Server 中,UNION 操作符用于将两个或多个 SELECT 语句的查询结果合并成一个结果集
如果说 JOIN 是根据列把两张表“横向”拼接起来,那么 UNION 就是把多个查询结果“纵向”堆叠在一起
基本语法: SELECT 列名1, 列名2 FROM 表1 UNION SELECT 列名1, 列名2 FROM 表2;
UNION 与 UNION ALL 的区别:UNION:合并数据 + 自动去重,UNION ALL:合并数据 + 保留所有行
🚩 常用场景与代码示例
假设我们有两个表:Employees(正式员工)和 Contractors(外包人员),我们想生成一份包含所有人员名字的名单
-- 查询正式员工的名字 SELECT Name, '正式员工' AS Type FROM Employees UNION -- 查询外包人员的名字 SELECT Name, '外包人员' AS Type FROM Contractors;
在 SQL Server 中,子查询(Subquery)就是一个嵌套在另一个查询(如 SELECT、INSERT、UPDATE 或 DELETE)内部的查询语句
🚩 内部查询完全独立,不依赖外部查询的任何数据,可以单独拿出来执行,数据库引擎通常只会执行它一次
-- 查询薪资高于公司平均薪资的员工 SELECT Name, Salary FROM Employees WHERE Salary > ( -- 这是一个自包含子查询,先算出平均薪资 SELECT AVG(Salary) FROM Employees );
🚩这种子查询不能独立执行,它必须引用外部查询中的列,外部查询每处理一行数据,内部查询就会跟着执行一次
-- 查询每个部门中薪资最高的员工 SELECT e1.Name, e1.Department, e1.Salary FROM Employees e1 WHERE e1.Salary = ( -- 内部查询引用了外部查询的 e1.Department SELECT MAX(Salary) FROM Employees e2 WHERE e2.Department = e1.Department );
-- 多值子查询:查询属于“销售部”或“人事部”的所有员工 SELECT Name FROM Employees WHERE DepartmentID IN ( SELECT ID FROM Departments WHERE Name IN ('销售部', '人事部') );
嵌套查询就是子查询的另一种叫法,你可以把它们理解为概念:只要是把一个 SELECT 查询语句“嵌套”在另一个查询(如 SELECT、INSERT、UPDATE、DELETE)内部的,都统称为嵌套查询
SELECT * FROM TableA WHERE ID IN (SELECT ID FROM TableB);
-- 这是一个两层嵌套的例子 SELECT Name FROM Employees WHERE DepartmentID IN ( SELECT ID FROM Departments WHERE CompanyID IN ( SELECT ID FROM Companies WHERE CompanyName = '阿里巴巴' ) );
在 SQL Server 中,连接查询(JOIN) 是关系型数据库最核心的功能,它的主要作用是将两张或多张表中的数据,
根据它们之间共有的关联字段(通常是主键和外键)“横向”拼接在一起,从而在一个查询结果中获取分散在不同表里的完整信息
ON 子句是连接查询(JOIN)的“粘合剂”和“匹配规则”,它紧跟在 JOIN 关键字之后,用来指定两张表之间通过哪些列进行关联,如果没有 ON 子句,数据库就不知道怎么把两张表的数据拼在一起
🚩 内连接是最常用、也是默认的连接方式,它只返回两张表中满足连接条件的交集数据,如果某行数据在另一张表中找不到匹配项,这行数据就不会出现在结果中
-- 查询有部门信息的员工(没有分配部门的员工会被过滤掉) SELECT e.Name, d.DepartmentName FROM Employees e INNER JOIN Departments d ON e.DeptID = d.ID;
🚩 以 JOIN 关键字左边的表为主表,它会返回左表中的所有行,即使右表中没有匹配的数据,如果右表没有匹配项,结果集中右表的列会显示为 NULL
-- 查询所有员工及其部门信息(即使员工还没分配部门,也会显示员工名字,部门显示为 NULL) SELECT e.Name, d.DepartmentName FROM Employees e LEFT JOIN Departments d ON e.DeptID = d.ID;
与左连接相反,以 JOIN 关键字右边的表为主表,它会返回右表中的所有行,即使左表中没有匹配的数据
左表和右表的数据全部保留,无论是否匹配,两张表的所有行都会出现在结果集中,没有匹配到的部分,缺失的一侧会显示为 NULL
-- 查询所有员工和所有部门(无论有没有匹配上,全部显示) SELECT e.Name, d.DepartmentName FROM Employees e FULL JOIN Departments d ON e.DeptID = d.ID;
🚩 在 SQL Server 中,CROSS JOIN 是最简单、也最“暴力”的一种连接方式,它的核心作用是将左表的每一行与右表的每一行进行组合,生成一个“笛卡尔积”
假设我们有一张颜色表(3行)和一张尺码表(3行):交叉连接后,结果为9行
-- 颜色表:红色、蓝色、绿色 -- 尺码表:S、M、L SELECT c.ColorName, s.SizeName FROM Colors c CROSS JOIN Sizes s;
基本语法: SELECT 列名 FROM 表1, 表2 WHERE 表1.关联列 = 表2.关联列;
-- 隐式内连接:查询员工姓名和部门名称 SELECT e.Name, d.DepartmentName FROM Employees e, Departments d WHERE e.DeptID = d.ID; -- 显式内连接(现代标准写法) SELECT e.Name, d.DepartmentName FROM Employees e INNER JOIN Departments d ON e.DeptID = d.ID; --3张以上表写法 -- 显式内连接(三张表标准写法) SELECT e.Name, d.DepartmentName, c.CompanyName FROM Employees e INNER JOIN Departments d ON e.DeptID = d.ID -- 第一步:员工表 关联 部门表 INNER JOIN Companies c ON d.CompanyID = c.ID; -- 第二步:部门表 关联 公司表
不推荐这种隐式写法,简单来说,把多表连接写在 WHERE 里属于“上个时代的产物”,了解它的原理有助于你读懂老代码
在 SQL Server 中,CASE 函数是 SQL 中唯一的条件逻辑表达式,它的作用像 if…else 或 switch 语句,允许你在查询结果中根据不同的条件返回不同的值
CASE WHEN 条件1 THEN 结果1 WHEN 条件2 THEN 结果2 ELSE 默认结果 END
CASE 字段名 WHEN 值1 THEN 结果1 WHEN 值2 THEN 结果2 ELSE 默认结果 END
🚩 常用场景与代码示例
-- 将状态码翻译成中文 SELECT Name, CASE Status WHEN 1 THEN '在职' WHEN 0 THEN '离职' ELSE '未知' END AS StatusText FROM Employees;
-- 根据薪资范围划分等级 SELECT Name, Salary, CASE WHEN Salary >= 20000 THEN '高薪' WHEN Salary >= 10000 THEN '中等' ELSE '低薪' END AS SalaryLevel FROM Employees;
--在聚合函数中使用(行转列统计) --这是 CASE 非常高级且实用的用法,常用于生成复杂的统计报表 -- 统计各部门中,薪资高于1万和低于1万的人数 SELECT Department, SUM(CASE WHEN Salary >= 10000 THEN 1 ELSE 0 END) AS HighSalaryCount, SUM(CASE WHEN Salary < 10000 THEN 1 ELSE 0 END) AS LowSalaryCount FROM Employees GROUP BY Department;
在 SQL Server 中,视图(View) 本质上是一个保存下来的、带有名字的查询语句,你可以把它想象成一张“虚拟表”,视图本身并不存储具体的数据(除非是特殊的索引视图)
它只存储了 SELECT 查询的定义,当你查询视图时,数据库会在后台动态执行这段保存好的 SQL 语句,并返回结果
基本语法: CREATE VIEW 视图名称 AS SELECT 列名1, 列名2 FROM 表名 WHERE 筛选条件;
查询视图: SELECT * FROM 视图名称;
修改视图: ALTER VIEW 视图名称 AS SELECT 列名1, 列名2 FROM 表名 WHERE 筛选条件;
向视图添加数据: 新添加的数据储存在与视图相关的表中,对原表不影响
🚩 INSERT INTO 视图名称(Name, Department, Salary)VALUES ('张三', '销售部', 12000.00);
删除视图: DROP VIEW 视图名称;
重命名视图: exec sp_rename 视图名称