news 2026/8/9 6:15:12

T-SQL 从入门到精通:建库建表、模糊查询与高级查询实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
T-SQL 从入门到精通:建库建表、模糊查询与高级查询实战指南

1. 引言

T-SQL(Transact-SQL)是 Microsoft SQL Server 和 Azure SQL Database 使用的 SQL 方言,它在标准 SQL 的基础上扩展了变量、流程控制、错误处理等功能,是数据库开发与管理的核心语言。无论是初学者还是有经验的开发者,掌握 T-SQL 的建库建表、数据查询(尤其是模糊查询和高级查询)都是必备技能。本文将系统性地讲解这些核心操作,并提供大量可直接运行的代码示例。

2. 数据库与数据表操作

2.1 创建数据库

使用CREATE DATABASE语句创建数据库,可以指定文件组、文件大小和增长策略。

-- 创建名为 SampleDB 的数据库 CREATE DATABASE SampleDB ON PRIMARY ( NAME = SampleDB_Data, FILENAME = 'C:\SQLData\SampleDB.mdf', SIZE = 10MB, MAXSIZE = 100MB, FILEGROWTH = 5MB ) LOG ON ( NAME = SampleDB_Log, FILENAME = 'C:\SQLData\SampleDB.ldf', SIZE = 5MB, MAXSIZE = 50MB, FILEGROWTH = 2MB ); GO -- 切换到新创建的数据库 USE SampleDB; GO

2.2 创建数据表

使用CREATE TABLE语句定义表结构,包括列名、数据类型、约束(主键、外键、非空、默认值等)。

-- 创建员工表 Employees CREATE TABLE Employees ( EmployeeID INT IDENTITY(1,1) PRIMARY KEY, -- 自增主键 FirstName NVARCHAR(50) NOT NULL, LastName NVARCHAR(50) NOT NULL, Email NVARCHAR(100) UNIQUE, -- 唯一约束 HireDate DATE DEFAULT GETDATE(), -- 默认值为当前日期 DepartmentID INT, Salary DECIMAL(10, 2) CHECK (Salary >= 0), -- 检查约束 CONSTRAINT FK_Employees_Departments FOREIGN KEY (DepartmentID) REFERENCES Departments(DepartmentID) -- 外键约束 ); -- 创建部门表 Departments CREATE TABLE Departments ( DepartmentID INT IDENTITY(1,1) PRIMARY KEY, DepartmentName NVARCHAR(100) NOT NULL, Location NVARCHAR(100) ); GO

2.3 修改与删除表

-- 为 Employees 表添加新列 ALTER TABLE Employees ADD PhoneNumber NVARCHAR(20); -- 修改列的数据类型 ALTER TABLE Employees ALTER COLUMN PhoneNumber VARCHAR(15); -- 删除表中的列 ALTER TABLE Employees DROP COLUMN PhoneNumber; -- 删除表(谨慎操作!) DROP TABLE Employees; DROP TABLE Departments; -- 删除数据库(谨慎操作!) DROP DATABASE SampleDB;

3. 模糊查询(LIKE 与通配符)

模糊查询用于匹配部分字符串,是数据检索中非常实用的功能,主要使用LIKE运算符配合通配符。

3.1 通配符详解

  • %:匹配任意长度(包括零长度)的任意字符序列。
  • _:匹配任意单个字符。
  • []:匹配指定范围或集合内的任意单个字符。
  • [^]:匹配不在指定范围或集合内的任意单个字符。

3.2 基础模糊查询示例

-- 假设我们有一个 Products 表,包含 ProductName 列 -- 1. 查找以 'Apple' 开头的产品 SELECT * FROM Products WHERE ProductName LIKE 'Apple%'; -- 2. 查找以 'Phone' 结尾的产品 SELECT * FROM Products WHERE ProductName LIKE '%Phone'; -- 3. 查找包含 'Pro' 的产品 SELECT * FROM Products WHERE ProductName LIKE '%Pro%'; -- 4. 查找第二个字符是 'a' 的产品名 SELECT * FROM Products WHERE ProductName LIKE '_a%'; -- 5. 查找以 'A' 或 'B' 或 'C' 开头的产品 SELECT * FROM Products WHERE ProductName LIKE '[ABC]%'; -- 6. 查找不以 'A'、'B'、'C' 开头的产品 SELECT * FROM Products WHERE ProductName LIKE '[^ABC]%'; -- 7. 结合使用:查找名称长度为5,且以 'Pro' 结尾的产品 SELECT * FROM Products WHERE ProductName LIKE '__Pro'; -- 两个下划线代表两个任意字符

3.3 转义通配符

当需要搜索包含通配符本身(如 % 或 _)的字符串时,需要使用ESCAPE子句。

-- 查找包含下划线 '_' 的产品名 SELECT * FROM Products WHERE ProductName LIKE '%\_%' ESCAPE '\'; -- 查找以 '25%' 开头的折扣信息 SELECT * FROM Discounts WHERE DiscountCode LIKE '25!%%' ESCAPE '!'; -- 使用 ! 作为转义符

4. 高级查询技巧

4.1 子查询

子查询是嵌套在主查询中的查询,可用于WHEREFROMSELECT等子句中。

-- 标量子查询(返回单个值) -- 查找薪水高于平均薪水的员工 SELECT FirstName, LastName, Salary FROM Employees WHERE Salary > (SELECT AVG(Salary) FROM Employees); -- 列子查询(返回一列多行) -- 查找在 'Sales' 或 'Marketing' 部门的员工 SELECT EmployeeID, FirstName, LastName FROM Employees WHERE DepartmentID IN ( SELECT DepartmentID FROM Departments WHERE DepartmentName IN ('Sales', 'Marketing') ); -- 行子查询(返回一行多列) -- 查找与特定员工(ID=101)部门和薪水都相同的其他员工 SELECT EmployeeID, FirstName, LastName FROM Employees WHERE (DepartmentID, Salary) = ( SELECT DepartmentID, Salary FROM Employees WHERE EmployeeID = 101 ) AND EmployeeID != 101; -- 表子查询(在 FROM 子句中作为派生表) -- 计算每个部门的员工数量和平均薪水 SELECT d.DepartmentName, emp_stats.EmployeeCount, emp_stats.AvgSalary FROM Departments d JOIN ( SELECT DepartmentID, COUNT(*) AS EmployeeCount, AVG(Salary) AS AvgSalary FROM Employees GROUP BY DepartmentID ) emp_stats ON d.DepartmentID = emp_stats.DepartmentID;

4.2 连接查询(JOIN)

-- 内连接(INNER JOIN):只返回两个表都匹配的行 SELECT e.FirstName, e.LastName, d.DepartmentName FROM Employees e INNER JOIN Departments d ON e.DepartmentID = d.DepartmentID; -- 左外连接(LEFT JOIN):返回左表所有行,右表匹配不上则为 NULL SELECT e.FirstName, e.LastName, d.DepartmentName FROM Employees e LEFT JOIN Departments d ON e.DepartmentID = d.DepartmentID; -- 右外连接(RIGHT JOIN):返回右表所有行,左表匹配不上则为 NULL SELECT e.FirstName, e.LastName, d.DepartmentName FROM Employees e RIGHT JOIN Departments d ON e.DepartmentID = d.DepartmentID; -- 全外连接(FULL JOIN):返回两个表的所有行,匹配不上则为 NULL SELECT e.FirstName, e.LastName, d.DepartmentName FROM Employees e FULL JOIN Departments d ON e.DepartmentID = d.DepartmentID; -- 交叉连接(CROSS JOIN):返回两个表的笛卡尔积 SELECT e.FirstName, d.DepartmentName FROM Employees e CROSS JOIN Departments d;

4.3 窗口函数

窗口函数在不减少行数的情况下,对一组行进行计算,非常适合排名、累计、移动平均等分析。

-- ROW_NUMBER(): 为结果集中的每一行分配一个唯一的序号 SELECT EmployeeID, FirstName, LastName, Salary, DepartmentID, ROW_NUMBER() OVER (PARTITION BY DepartmentID ORDER BY Salary DESC) AS DeptSalaryRank FROM Employees; -- RANK() 和 DENSE_RANK(): 处理并列排名 SELECT EmployeeID, FirstName, Salary, DepartmentID, RANK() OVER (PARTITION BY DepartmentID ORDER BY Salary DESC) AS RankWithGaps, DENSE_RANK() OVER (PARTITION BY DepartmentID ORDER BY Salary DESC) AS RankNoGaps FROM Employees; -- 累计求和与移动平均 SELECT OrderDate, DailySales, SUM(DailySales) OVER (ORDER BY OrderDate) AS CumulativeSales, AVG(DailySales) OVER (ORDER BY OrderDate ROWS BETWEEN 2 PRECEDING AND CURRENT ROW) AS MovingAvg3Days FROM SalesDaily;

4.4 公用表表达式(CTE)

CTE 使复杂查询更清晰、易读,支持递归查询。

-- 非递归 CTE:计算部门平均薪水并筛选 WITH DeptAvgSalary AS ( SELECT DepartmentID, AVG(Salary) AS AvgSalary FROM Employees GROUP BY DepartmentID ) SELECT e.FirstName, e.LastName, e.Salary, d.DepartmentName, das.AvgSalary FROM Employees e JOIN Departments d ON e.DepartmentID = d.DepartmentID JOIN DeptAvgSalary das ON e.DepartmentID = das.DepartmentID WHERE e.Salary > das.AvgSalary; -- 递归 CTE:生成组织结构树(假设 Employees 表有 ManagerID 列) WITH OrgHierarchy AS ( -- 锚点成员:顶级管理者(ManagerID IS NULL) SELECT EmployeeID, FirstName, LastName, ManagerID, 1 AS Level FROM Employees WHERE ManagerID IS NULL UNION ALL -- 递归成员:下属员工 SELECT e.EmployeeID, e.FirstName, e.LastName, e.ManagerID, oh.Level + 1 FROM Employees e INNER JOIN OrgHierarchy oh ON e.ManagerID = oh.EmployeeID ) SELECT * FROM OrgHierarchy ORDER BY Level, EmployeeID;

4.5 动态 SQL

动态 SQL 允许在运行时构建和执行 SQL 语句,灵活性高但需注意 SQL 注入风险。

-- 声明变量 DECLARE @TableName NVARCHAR(128) = N'Employees'; DECLARE @ColumnName NVARCHAR(128) = N'FirstName'; DECLARE @SearchValue NVARCHAR(100) = N'John'; DECLARE @SQL NVARCHAR(MAX); -- 构建动态 SQL 语句(使用参数化查询防止 SQL 注入) SET @SQL = N'SELECT * FROM ' + QUOTENAME(@TableName) + N' WHERE ' + QUOTENAME(@ColumnName) + N' LIKE @Value'; -- 执行动态 SQL EXEC sp_executesql @SQL, N'@Value NVARCHAR(100)', @Value = @SearchValue + N'%';

5. 性能优化与最佳实践

  • 索引是查询性能的基石:为频繁用于WHEREJOINORDER BY的列创建索引。
  • 避免在 WHERE 子句中对列进行函数操作:如WHERE YEAR(OrderDate) = 2023会导致索引失效,应改为WHERE OrderDate >= '2023-01-01' AND OrderDate < '2024-01-01'
  • 模糊查询优化:以通配符%开头的LIKE查询(如LIKE '%keyword')无法使用索引。如果业务允许,尽量使用后缀匹配(LIKE 'keyword%')。
  • 使用 EXISTS 代替 IN:当子查询返回大量数据时,EXISTS通常比IN性能更好。
  • 选择合适的数据类型:使用最小的、最合适的数据类型(如用INT而不是BIGINT)可以节省存储空间并提升查询速度。

6. 总结

本文系统介绍了 T-SQL 中建库建表、模糊查询和高级查询的核心知识与实战技巧。从基础的CREATE DATABASE/TABLE到灵活的LIKE模糊匹配,再到复杂的子查询、连接、窗口函数和 CTE,这些是进行高效数据库开发与数据分析的必备武器。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/9 6:13:34

AI编程工具市场风向:从Claude强制认证到Coding Plan走红的竞争逻辑

1. 从“刷脸”到“抢码”&#xff1a;一个开发者工具市场的风向标最近AI圈和开发者社区里&#xff0c;两件看似不相关的事被放在一起讨论&#xff0c;形成了强烈的对比。一边是海外明星AI产品Claude&#xff0c;其开发者平台Anthropic Console开始强制要求部分用户进行人脸识别…

作者头像 李华
网站建设 2026/8/9 6:13:29

从临时脚本到自动化流程:媒体批处理工具的工程实践与思考

最近在整理本地文件时&#xff0c;发现了一个有趣的现象&#xff1a;我电脑里散落着几十个以“test”、“demo”、“tmp”命名的文件夹和脚本。它们大多是一次性实验的产物&#xff0c;比如尝试一个新工具、验证一个想法&#xff0c;或者临时处理一批文件。当时觉得“先跑通再说…

作者头像 李华
网站建设 2026/8/9 6:11:56

Unity Animator与Transform冲突解析:代码控制失效的根源与解决方案

1. 项目概述&#xff1a;当代码指令在Animator面前“失效”在Unity开发中&#xff0c;尤其是涉及角色动画时&#xff0c;很多开发者都踩过这样一个坑&#xff1a;你写了一段逻辑清晰的代码&#xff0c;试图通过transform.position或transform.localPosition来移动你的角色或某个…

作者头像 李华
网站建设 2026/8/9 6:11:44

Unity3D跑酷游戏源码深度解析与个性化改造实战指南

1. 项目概述&#xff1a;从源码到个性化跑酷游戏的捷径如果你对Unity3D游戏开发感兴趣&#xff0c;尤其是想快速上手制作一款属于自己的跑酷游戏&#xff0c;那么一份高质量的源码就是你的“火箭燃料”。跑酷游戏&#xff0c;以其快节奏、易上手、高反馈的特点&#xff0c;一直…

作者头像 李华
网站建设 2026/8/9 6:10:44

【C语言6】指针

文章目录6. 指针6.1 指针基础6.1.1 指针变量的定义6.1.2 指针变量的初始化和赋值6.1.3 指针运算符6.2 指针的算数运算6.3 指针作为函数参数6.4 指针和数组6.4.1 指针和一维整型数组6.4.2 指针和一维字符型数组6.4.3 数组指针6.4.4 指针和二维数组6.4.5 指针数组6.5 二级指针6.6…

作者头像 李华
网站建设 2026/8/9 6:10:18

MyBatis-Plus分页机制深度解析与性能优化

1. MyBatis-Plus分页机制原理解析MyBatis-Plus的分页功能本质上是对MyBatis原生分页的增强封装。其核心实现原理是通过ThreadLocal保存分页参数&#xff0c;在执行SQL前动态拦截并重写语句。具体工作流程如下&#xff1a;调用Page构造函数创建分页对象时&#xff0c;会自动将分…

作者头像 李华