SQL Server 2019入门学习教程,从入门到精通,认识函数 —语法详解与实战案例(SQL Server 2019)(7)

认识函数 ---语法详解与实战案例(SQL Server 2019)


一、SQL Server 2019 函数简介

函数是预定义的、可重用的代码块,用于执行特定操作并返回结果。

分类:

  • 标量函数 :返回单个值(如 LEN(), GETDATE()
  • 聚合函数 :对一组值执行计算(如 SUM(), AVG()
  • 窗口函数 :在结果集的"窗口"上执行计算(如 ROW_NUMBER()
  • 系统函数:返回服务器/数据库/对象元数据信息

二、字符串函数(String Functions)

用于处理和操作字符数据。

2.1 ASCII() 函数

返回字符表达式最左端字符的 ASCII 码值

sql 复制代码
SELECT ASCII('A') AS ASCIICode; -- 返回 65
SELECT ASCII('a') AS ASCIICode; -- 返回 97
SELECT ASCII('中') AS ASCIICode; -- 返回 20013(Unicode)

2.2 CHAR() 函数

将 ASCII 码值转换为字符(0~255)

sql 复制代码
SELECT CHAR(65) AS CharA;  -- 'A'
SELECT CHAR(97) AS Chara;  -- 'a'
SELECT CHAR(48) AS Char0;  -- '0'
-- 超过255会返回NULL
SELECT CHAR(256) AS Result; -- NULL

2.3 LEFT() 函数

从字符串左侧开始,返回指定长度的字符

sql 复制代码
SELECT LEFT('Hello World', 5) AS LeftPart; -- 'Hello'
SELECT LEFT('SQL Server', 3) AS LeftPart;  -- 'SQL'
-- 处理中文
SELECT LEFT('数据库管理系统', 3) AS LeftPart; -- '数据库'

2.4 RIGHT() 函数

从字符串右侧开始,返回指定长度的字符

sql 复制代码
SELECT RIGHT('Hello World', 5) AS RightPart; -- 'World'
SELECT RIGHT('SQL Server 2019', 4) AS RightPart; -- '2019'
SELECT RIGHT('数据库管理系统', 2) AS RightPart; -- '系统'

2.5 LTRIM() 函数

去除字符串左侧的空格

sql 复制代码
SELECT LTRIM('   Hello') AS Trimmed; -- 'Hello'
SELECT LTRIM('   SQL Server   ') AS Trimmed; -- 'SQL Server   '(右侧空格保留)

2.6 RTRIM() 函数

去除字符串右侧的空格

sql 复制代码
SELECT RTRIM('Hello   ') AS Trimmed; -- 'Hello'
SELECT RTRIM('   SQL Server   ') AS Trimmed; -- '   SQL Server'(左侧空格保留)

2.7 STR() 函数

将数值转换为字符型(可指定长度和小数位数)

sql 复制代码
SELECT STR(123.456, 10, 2) AS StrResult; -- '    123.46'(总长10,右对齐)
SELECT STR(123.456, 6, 1) AS StrResult;  -- ' 123.5'
SELECT STR(999.999, 5, 2) AS StrResult;  -- '*****'(溢出时返回星号)

2.8 REVERSE() 函数

返回字符串的逆序

sql 复制代码
SELECT REVERSE('Hello') AS Reversed; -- 'olleH'
SELECT REVERSE('12345') AS Reversed; -- '54321'
SELECT REVERSE('上海自来水来自海上') AS Reversed; -- '上海来自水自来海上'(回文验证)

2.9 LEN() 函数

返回字符串的字符数(不包括尾随空格)

sql 复制代码
SELECT LEN('Hello') AS Length; -- 5
SELECT LEN('Hello   ') AS Length; -- 5(尾部空格不计)
SELECT LEN('数据库') AS Length; -- 3
SELECT LEN('') AS Length; -- 0

2.10 CHARINDEX() 函数(匹配子串开始位置)

返回子串在字符串中第一次出现的位置(从1开始,未找到返回0)

sql 复制代码
SELECT CHARINDEX('o', 'Hello World') AS Position; -- 5
SELECT CHARINDEX('SQL', 'Microsoft SQL Server') AS Position; -- 11
SELECT CHARINDEX('x', 'Hello') AS Position; -- 0(未找到)
-- 可指定起始位置
SELECT CHARINDEX('o', 'Hello World', 6) AS Position; -- 8(从第6位开始找)

2.11 SUBSTRING() 函数

从字符串中提取子串(起始位置从1开始)

sql 复制代码
SELECT SUBSTRING('Hello World', 7, 5) AS SubStr; -- 'World'
SELECT SUBSTRING('SQL Server 2019', 1, 3) AS SubStr; -- 'SQL'
SELECT SUBSTRING('数据库管理系统', 3, 2) AS SubStr; -- '管理'

2.12 LOWER() 函数

将字符串转换为小写

sql 复制代码
SELECT LOWER('HELLO WORLD') AS LowerCase; -- 'hello world'
SELECT LOWER('SQL Server') AS LowerCase; -- 'sql server'

2.13 UPPER() 函数

将字符串转换为大写

sql 复制代码
SELECT UPPER('hello world') AS UpperCase; -- 'HELLO WORLD'
SELECT UPPER('sql server') AS UpperCase; -- 'SQL SERVER'

2.14 REPLACE() 函数

替换字符串中的子串

sql 复制代码
SELECT REPLACE('Hello World', 'World', 'SQL Server') AS Replaced; -- 'Hello SQL Server'
SELECT REPLACE('123-456-789', '-', '') AS Replaced; -- '123456789'(删除所有-)
SELECT REPLACE('abcabcabc', 'abc', 'xyz') AS Replaced; -- 'xyzxyzxyz'

三、数学函数(Mathematical Functions)

用于执行数学运算。

3.1 ABS(x) 函数

返回绝对值

sql 复制代码
SELECT ABS(-10) AS Absolute; -- 10
SELECT ABS(10) AS Absolute;  -- 10
SELECT ABS(-3.14) AS Absolute; -- 3.14

3.2 PI() 函数

返回圆周率 π

sql 复制代码
SELECT PI() AS PiValue; -- 3.14159265358979
SELECT ROUND(PI(), 2) AS PiRounded; -- 3.14

3.3 SQRT(x) 函数

返回平方根

sql 复制代码
SELECT SQRT(16) AS SquareRoot; -- 4
SELECT SQRT(2) AS SquareRoot;  -- 1.4142135623731
SELECT SQRT(ABS(-25)) AS SquareRoot; -- 5(负数先取绝对值)

3.4 RAND() 和 RAND(x) 函数

返回0到1之间的随机浮点数
RAND(x):x为种子,相同种子返回相同随机数

sql 复制代码
SELECT RAND() AS RandomNumber; -- 如 0.123456789
SELECT RAND(100) AS RandomWithSeed; -- 每次执行都相同(如0.715436657)
SELECT RAND(100) AS RandomWithSeedAgain; -- 同上,相同种子相同结果

-- 生成1到100的随机整数
SELECT FLOOR(RAND() * 100) + 1 AS RandomInt1To100;

3.5 ROUND(x, y) 函数

四舍五入到指定小数位

sql 复制代码
SELECT ROUND(123.456, 2) AS Rounded; -- 123.460
SELECT ROUND(123.456, 1) AS Rounded; -- 123.500
SELECT ROUND(123.456, 0) AS Rounded; -- 123.000
SELECT ROUND(123.456, -1) AS Rounded; -- 120.000(对十位四舍五入)
SELECT ROUND(123.456, -2) AS Rounded; -- 100.000(对百位四舍五入)

3.6 SIGN(x) 函数

返回符号:正数=1,负数=-1,零=0

sql 复制代码
SELECT SIGN(10) AS Sign;  -- 1
SELECT SIGN(-5) AS Sign;  -- -1
SELECT SIGN(0) AS Sign;   -- 0
SELECT SIGN(-3.14) AS Sign; -- -1

3.7 CEILING(x) 和 FLOOR(x) 函数

CEILING:向上取整(天花板)
FLOOR:向下取整(地板)

sql 复制代码
SELECT CEILING(3.14) AS Ceiling; -- 4
SELECT CEILING(-3.14) AS Ceiling; -- -3(注意负数)
SELECT FLOOR(3.14) AS Floor;     -- 3
SELECT FLOOR(-3.14) AS Floor;    -- -4(注意负数)

3.8 POWER(x, y), SQUARE(x), EXP(x) 函数

POWER:x的y次方
SQUARE:x的平方(=POWER(x,2))
EXP:e的x次方

sql 复制代码
SELECT POWER(2, 3) AS PowerResult; -- 8
SELECT POWER(10, 2) AS PowerResult; -- 100
SELECT SQUARE(5) AS SquareResult;  -- 25
SELECT EXP(1) AS ExpResult;        -- 2.71828182845905(e^1)
SELECT EXP(2) AS ExpResult;        -- 7.38905609893065(e^2)

3.9 LOG(x) 和 LOG10(x) 函数

LOG:自然对数(以e为底)
LOG10:常用对数(以10为底)

sql 复制代码
SELECT LOG(EXP(1)) AS LogResult; -- 1(ln(e) = 1)
SELECT LOG(10) AS LogResult;     -- 2.30258509299405
SELECT LOG10(100) AS Log10Result; -- 2
SELECT LOG10(1000) AS Log10Result; -- 3

3.10 RADIANS(x) 和 DEGREES(x) 函数

角度与弧度转换

sql 复制代码
SELECT RADIANS(180) AS Radians; -- 3.14159265358979(π)
SELECT DEGREES(PI()) AS Degrees; -- 180
SELECT RADIANS(90) AS Radians;  -- 1.5707963267949
SELECT DEGREES(1.5707963267949) AS Degrees; -- 90

3.11 SIN(x), ASIN(x), COS(x), ACOS(x) 函数

三角函数(参数为弧度)

sql 复制代码
SELECT SIN(RADIANS(30)) AS Sin30; -- 0.5
SELECT ASIN(0.5) AS Asin05;       -- 0.523598775598299(弧度)
SELECT DEGREES(ASIN(0.5)) AS Asin05Degrees; -- 30
SELECT COS(RADIANS(60)) AS Cos60; -- 0.5
SELECT ACOS(0.5) AS Acos05;       -- 1.0471975511966(弧度)
SELECT DEGREES(ACOS(0.5)) AS Acos05Degrees; -- 60

3.12 TAN(x), ATAN(x), COT(x) 函数

正切、反正切、余切

sql 复制代码
SELECT TAN(RADIANS(45)) AS Tan45; -- 1
SELECT ATAN(1) AS Atan1;          -- 0.785398163397448(π/4弧度)
SELECT DEGREES(ATAN(1)) AS Atan1Degrees; -- 45
SELECT COT(RADIANS(45)) AS Cot45; -- 1(余切=1/正切)

四、数据类型转换函数

主要使用 CAST()CONVERT()

4.1 CAST() 函数

sql 复制代码
SELECT CAST('123' AS INT) AS IntValue; -- 123
SELECT CAST(123.45 AS VARCHAR(10)) AS StrValue; -- '123.45'
SELECT CAST(GETDATE() AS DATE) AS DateOnly; -- 2025-09-13
SELECT CAST('2025-09-13' AS DATETIME) AS DateTimeValue; -- 2025-09-13 00:00:00.000

4.2 CONVERT() 函数(更灵活,支持格式化)

sql 复制代码
SELECT CONVERT(VARCHAR(10), GETDATE(), 120) AS Format1; -- '2025-09-13'
SELECT CONVERT(VARCHAR(19), GETDATE(), 120) AS Format2; -- '2025-09-13 20:56:00'
SELECT CONVERT(VARCHAR(8), GETDATE(), 108) AS TimeOnly; -- '20:56:00'
SELECT CONVERT(DECIMAL(10,2), '123.456') AS DecimalValue; -- 123.46

五、文本函数和图像函数(TEXT/IMAGE 类型已过时,建议用 VARCHAR(MAX)/VARBINARY(MAX))

SQL Server 2005+ 已推荐使用 VARCHAR(MAX), NVARCHAR(MAX), VARBINARY(MAX)

但为兼容性仍支持以下函数:

5.1 TEXTPTR() 函数

返回指向 text, ntext, image 列的指针(二进制值)

sql 复制代码
-- 创建含TEXT列的表(仅演示,实际不推荐)
CREATE TABLE OldTable (
    ID INT PRIMARY KEY,
    Content TEXT
);
GO

INSERT INTO OldTable VALUES (1, 'This is a long text content...');
GO

-- 获取文本指针
SELECT TEXTPTR(Content) AS TextPointer FROM OldTable WHERE ID = 1;
-- 返回如:0x0000000000000700000000000000...
GO

DROP TABLE OldTable;

5.2 TEXTVALID() 函数

检查文本指针是否有效

sql 复制代码
-- 假设有表和数据
-- SELECT TEXTVALID('OldTable.Content', TEXTPTR(Content)) AS IsValid FROM OldTable;
-- 返回1表示有效,0表示无效

💡 现代替代方案 :直接操作 VARCHAR(MAX),无需指针。


六、日期和时间函数(Date and Time Functions)

6.1 GETDATE() 函数

返回当前系统日期和时间(datetime类型)

sql 复制代码
SELECT GETDATE() AS CurrentDateTime; -- 2025-09-13 20:56:00.123

6.2 GETUTCDATE() 函数

返回当前UTC(协调世界时)日期和时间

sql 复制代码
SELECT GETUTCDATE() AS UTCDateTime; -- 如:2025-09-13 12:56:00.123(UTC时间)

6.3 DAY(d), MONTH(d), YEAR(d) 函数

提取日期中的天、月、年

sql 复制代码
DECLARE @Date DATE = '2025-09-13';
SELECT 
    DAY(@Date) AS DayPart,   -- 13
    MONTH(@Date) AS MonthPart, -- 9
    YEAR(@Date) AS YearPart;  -- 2025

6.4 DATENAME(dp, d) 函数

返回日期指定部分的字符串

sql 复制代码
SELECT DATENAME(YEAR, GETDATE()) AS YearName; -- '2025'
SELECT DATENAME(MONTH, GETDATE()) AS MonthName; -- 'September'
SELECT DATENAME(DAY, GETDATE()) AS DayName; -- '13'
SELECT DATENAME(WEEKDAY, GETDATE()) AS WeekdayName; -- 'Saturday'
SELECT DATENAME(QUARTER, GETDATE()) AS QuarterName; -- '3'

6.5 DATEPART(dp, d) 函数

返回日期指定部分的整数

sql 复制代码
SELECT DATEPART(YEAR, GETDATE()) AS YearPart; -- 2025
SELECT DATEPART(MONTH, GETDATE()) AS MonthPart; -- 9
SELECT DATEPART(DAY, GETDATE()) AS DayPart; -- 13
SELECT DATEPART(WEEKDAY, GETDATE()) AS WeekdayPart; -- 7(周日=1,周六=7)
SELECT DATEPART(WEEK, GETDATE()) AS WeekOfYear; -- 当年第几周

6.6 DATEADD(dp, num, d) 函数

在日期上增加指定时间间隔

sql 复制代码
SELECT DATEADD(DAY, 7, GETDATE()) AS NextWeek; -- 7天后
SELECT DATEADD(MONTH, -1, GETDATE()) AS LastMonth; -- 1个月前
SELECT DATEADD(YEAR, 1, GETDATE()) AS NextYear; -- 1年后
SELECT DATEADD(HOUR, 2, GETDATE()) AS TwoHoursLater; -- 2小时后

七、系统函数(System Functions)

返回数据库、服务器、对象等元数据信息。

7.1 COL_LENGTH() ------ 返回表中指定字段的长度值

sql 复制代码
-- 假设存在Students表
SELECT COL_LENGTH('Students', 'Name') AS NameLength; -- 如:100(NVARCHAR(50)占100字节)
SELECT COL_LENGTH('Students', 'StudentNo') AS StudentNoLength; -- 10(CHAR(10))

7.2 COL_NAME() ------ 返回表中指定字段的名称

sql 复制代码
-- 需要表ID和列ID
DECLARE @TableID INT = OBJECT_ID('Students');
SELECT 
    COL_NAME(@TableID, 1) AS Column1, -- 第1列名
    COL_NAME(@TableID, 2) AS Column2; -- 第2列名

7.3 DATALENGTH() ------ 返回数据表达式的实际字节长度

sql 复制代码
SELECT DATALENGTH('Hello') AS Len1; -- 5(VARCHAR)
SELECT DATALENGTH(N'Hello') AS Len2; -- 10(NVARCHAR,每个字符2字节)
SELECT DATALENGTH('数据库') AS Len3; -- 6(VARCHAR,假设中文占3字节)
SELECT DATALENGTH(N'数据库') AS Len4; -- 6(NVARCHAR,3字符×2字节=6)

7.4 DB_ID() 和 DB_NAME() ------ 数据库编号和名称

sql 复制代码
SELECT DB_ID() AS CurrentDBID; -- 当前数据库ID
SELECT DB_ID('master') AS MasterDBID; -- master数据库ID
SELECT DB_NAME() AS CurrentDBName; -- 当前数据库名
SELECT DB_NAME(1) AS DBName; -- ID=1的数据库名(通常是master)

7.5 GETANSINULL() ------ 返回当前数据库默认的NULL值处理

sql 复制代码
SELECT GETANSINULL() AS AnsiNullDefault; -- 1表示启用ANSI NULL默认值

7.6 @@SERVICENAME ------ 返回服务器实例名

sql 复制代码
SELECT @@SERVICENAME AS ServerInstanceName; -- 如:MSSQLSERVER 或 SQLEXPRESS

7.7 @@SERVERNAME ------ 返回服务器计算机名称

sql 复制代码
SELECT @@SERVERNAME AS ServerComputerName; -- 如:DESKTOP-XXXXX

7.8 OBJECT_ID() ------ 返回数据库对象的编号

sql 复制代码
SELECT OBJECT_ID('Students') AS StudentsTableID;
SELECT OBJECT_ID('vw_StudentClass') AS ViewID;

7.9 SUSER_SID() ------ 返回用户的SID(安全标识号)

sql 复制代码
SELECT SUSER_SID() AS CurrentUserSID; -- 当前登录用户的SID
SELECT SUSER_SID('sa') AS SASID; -- sa用户的SID

7.10 SUSER_NAME() ------ 返回用户的登录名

sql 复制代码
SELECT SUSER_NAME() AS CurrentLoginName; -- 当前登录名
SELECT SUSER_NAME(0x01) AS LoginName; -- 根据SID获取登录名

7.11 OBJECT_NAME() ------ 返回数据库对象的名称

sql 复制代码
SELECT OBJECT_NAME(OBJECT_ID('Students')) AS TableName; -- 'Students'

7.12 USER_ID() 和 USER_NAME() ------ 数据库用户的ID和名称

sql 复制代码
SELECT USER_ID() AS CurrentUserID; -- 当前数据库用户ID
SELECT USER_ID('dbo') AS DBOUserID; -- dbo用户ID
SELECT USER_NAME() AS CurrentUserName; -- 当前数据库用户名
SELECT USER_NAME(1) AS UserName; -- ID=1的用户名(通常是dbo)

八、窗口函数(Window Functions)

在结果集的"窗口"(分区)上执行计算,不减少行数。

8.1 ROW_NUMBER() ------ 行号

sql 复制代码
SELECT 
    Name,
    ClassID,
    ROW_NUMBER() OVER (ORDER BY Name) AS RowNum
FROM Students;

8.2 RANK() 和 DENSE_RANK() ------ 排名

sql 复制代码
-- 假设有成绩表
CREATE TABLE Scores (
    StudentName NVARCHAR(50),
    Score INT
);
INSERT INTO Scores VALUES 
('张三', 95), ('李四', 90), ('王五', 95), ('赵六', 85);

SELECT 
    StudentName,
    Score,
    RANK() OVER (ORDER BY Score DESC) AS Rank, -- 1,2,2,4(跳过重复名次)
    DENSE_RANK() OVER (ORDER BY Score DESC) AS DenseRank -- 1,2,2,3(不跳过)
FROM Scores;

8.3 NTILE() ------ 分组排名

sql 复制代码
SELECT 
    StudentName,
    Score,
    NTILE(3) OVER (ORDER BY Score DESC) AS Tier -- 分成3组
FROM Scores;

8.4 LEAD() 和 LAG() ------ 前后行值

sql 复制代码
SELECT 
    StudentName,
    Score,
    LAG(Score, 1, 0) OVER (ORDER BY Score DESC) AS PrevScore, -- 前一行分数
    LEAD(Score, 1, 0) OVER (ORDER BY Score DESC) AS NextScore  -- 后一行分数
FROM Scores;

8.5 SUM() OVER() ------ 累计求和

sql 复制代码
SELECT 
    StudentName,
    Score,
    SUM(Score) OVER (ORDER BY Score DESC ROWS UNBOUNDED PRECEDING) AS RunningTotal
FROM Scores;

九、综合性实战案例

🎯 案例19:学生数据清洗与标准化脚本

sql 复制代码
USE SchoolManagement;
GO

-- 创建示例数据(含脏数据)
IF OBJECT_ID('RawStudents', 'U') IS NOT NULL DROP TABLE RawStudents;
CREATE TABLE RawStudents (
    RawID INT IDENTITY(1,1),
    RawName NVARCHAR(100),
    RawGender NVARCHAR(10),
    RawBirthDate NVARCHAR(20),
    RawClass NVARCHAR(50),
    RawEmail NVARCHAR(100)
);
GO

INSERT INTO RawStudents VALUES
('  张三  ', '男', '2007-03-15', '高三(1)班', ' zhangsan@school.com '),
('Lisi', 'Female', '2008/07/22', '高二(2)班', 'lisi@school.com'),
('王五 ', 'M', '07-15-2006', '高一(3)班', 'wangwu@'),
('  赵六  ', '未知', '2007-12-32', '高三(1)班', 'zhaoliu@school.com'), -- 无效日期
('QianQi', 'F', '2008-02-29', '高二(2)班', 'qianqi@school.com'); -- 闰年有效
GO

-- ========== 数据清洗脚本 ==========
PRINT '📊 原始数据:';
SELECT * FROM RawStudents;
GO

-- 清洗后的学生表
IF OBJECT_ID('CleanStudents', 'U') IS NOT NULL DROP TABLE CleanStudents;
CREATE TABLE CleanStudents (
    StudentID INT IDENTITY(1,1) PRIMARY KEY,
    Name NVARCHAR(50) NOT NULL,
    Gender CHAR(1) CHECK (Gender IN ('M','F')),
    BirthDate DATE,
    ClassName NVARCHAR(50),
    Email NVARCHAR(100),
    CleanStatus NVARCHAR(50) -- 清洗状态
);
GO

-- 插入清洗后数据
INSERT INTO CleanStudents (Name, Gender, BirthDate, ClassName, Email, CleanStatus)
SELECT 
    -- 清洗姓名:去空格,取前50字符
    LEFT(LTRIM(RTRIM(RawName)), 50) AS Name,
    
    -- 清洗性别:映射中文和英文
    CASE 
        WHEN LOWER(LTRIM(RTRIM(RawGender))) IN ('男', 'm', 'male') THEN 'M'
        WHEN LOWER(LTRIM(RTRIM(RawGender))) IN ('女', 'f', 'female') THEN 'F'
        ELSE 'U' -- 未知
    END AS Gender,
    
    -- 清洗日期:尝试多种格式转换
    CASE 
        WHEN ISDATE(RawBirthDate) = 1 THEN CONVERT(DATE, RawBirthDate)
        WHEN ISDATE(REPLACE(RawBirthDate, '/', '-')) = 1 THEN CONVERT(DATE, REPLACE(RawBirthDate, '/', '-'))
        ELSE NULL -- 无效日期设为NULL
    END AS BirthDate,
    
    -- 班级:去空格
    LTRIM(RTRIM(RawClass)) AS ClassName,
    
    -- 邮箱:去空格,验证格式
    CASE 
        WHEN LTRIM(RTRIM(RawEmail)) LIKE '%@%.%' THEN LTRIM(RTRIM(RawEmail))
        ELSE NULL
    END AS Email,
    
    -- 清洗状态
    CASE 
        WHEN LTRIM(RTRIM(RawName)) = '' OR LTRIM(RTRIM(RawName)) IS NULL THEN '姓名为空'
        WHEN CASE 
                WHEN LOWER(LTRIM(RTRIM(RawGender))) IN ('男', 'm', 'male', '女', 'f', 'female') THEN 1
                ELSE 0 
             END = 0 THEN '性别无效'
        WHEN ISDATE(RawBirthDate) = 0 AND ISDATE(REPLACE(RawBirthDate, '/', '-')) = 0 THEN '日期无效'
        WHEN LTRIM(RTRIM(RawEmail)) NOT LIKE '%@%.%' THEN '邮箱格式无效'
        ELSE '清洗成功'
    END AS CleanStatus
FROM RawStudents;
GO

PRINT '✅ 数据清洗完成!';
PRINT '📋 清洗后数据:';
SELECT * FROM CleanStudents;
GO

-- 统计清洗结果
SELECT 
    CleanStatus,
    COUNT(*) AS RecordCount
FROM CleanStudents
GROUP BY CleanStatus;
GO

🎯 案例20:学生年龄分布报表(综合日期、数学、字符串函数)

sql 复制代码
USE SchoolManagement;
GO

-- 生成年龄分布报表
SELECT 
    -- 年龄分组
    CASE 
        WHEN Age < 16 THEN '15岁以下'
        WHEN Age BETWEEN 16 AND 18 THEN '16-18岁'
        WHEN Age BETWEEN 19 AND 22 THEN '19-22岁'
        ELSE '23岁以上'
    END AS AgeGroup,
    
    COUNT(*) AS StudentCount,
    MIN(Age) AS MinAge,
    MAX(Age) AS MaxAge,
    AVG(Age * 1.0) AS AvgAge, -- *1.0转为小数
    
    -- 用REPLICATE生成简单图表
    REPLICATE('■', COUNT(*) * 2) AS Chart,
    
    -- 百分比
    CAST(COUNT(*) * 100.0 / SUM(COUNT(*)) OVER() AS DECIMAL(5,2)) AS Percentage
FROM (
    SELECT 
        DATEDIFF(YEAR, BirthDate, GETDATE()) - 
        CASE 
            WHEN MONTH(BirthDate) > MONTH(GETDATE()) OR 
                 (MONTH(BirthDate) = MONTH(GETDATE()) AND DAY(BirthDate) > DAY(GETDATE()))
            THEN 1 
            ELSE 0 
        END AS Age -- 精确年龄计算
    FROM Students
    WHERE Status = 'A' AND BirthDate IS NOT NULL
) AS AgeData
GROUP BY 
    CASE 
        WHEN Age < 16 THEN '15岁以下'
        WHEN Age BETWEEN 16 AND 18 THEN '16-18岁'
        WHEN Age BETWEEN 19 AND 22 THEN '19-22岁'
        ELSE '23岁以上'
    END
ORDER BY MIN(Age);
GO

🎯 案例21:系统信息监控报表

sql 复制代码
-- 生成系统信息报告
SELECT 
    '服务器信息' AS Category,
    @@SERVERNAME AS ItemName,
    '服务器名称' AS Description
UNION ALL
SELECT '服务器信息', @@SERVICENAME, '服务实例名'
UNION ALL
SELECT '数据库信息', DB_NAME(), '当前数据库'
UNION ALL
SELECT '数据库信息', CAST(DB_ID() AS VARCHAR), '当前数据库ID'
UNION ALL
SELECT '用户信息', SUSER_NAME(), '当前登录名'
UNION ALL
SELECT '用户信息', USER_NAME(), '当前数据库用户名'
UNION ALL
SELECT '系统日期', CONVERT(VARCHAR, GETDATE(), 120), '当前系统时间'
UNION ALL
SELECT '系统日期', CONVERT(VARCHAR, GETUTCDATE(), 120), 'UTC时间'
UNION ALL
SELECT '版本信息', @@VERSION, 'SQL Server版本'
UNION ALL
SELECT '进程ID', CAST(@@SPID AS VARCHAR), '当前会话ID'
ORDER BY Category, ItemName;
GO

✅ 本章核心函数速查表

类别 函数 用途
字符串 LEFT, RIGHT, LEN, SUBSTRING, REPLACE, UPPER, LOWER 字符串截取、长度、替换、大小写转换
数学 ROUND, RAND, CEILING, FLOOR, POWER, SQRT 数值计算、随机数、取整、幂运算
日期 GETDATE, DATEADD, DATEDIFF, YEAR, MONTH, DAY 日期获取、计算、提取部分
系统 DB_NAME, USER_NAME, OBJECT_ID, @@SERVERNAME 获取数据库、用户、对象、服务器信息
转换 CAST, CONVERT 数据类型转换
窗口 ROW_NUMBER, RANK, SUM() OVER() 分区计算、排名、累计

📌 学习建议

  • 多练习组合使用函数(如 LEFT(LTRIM(RTRIM(...)))
  • 注意函数的参数类型和返回类型
  • 使用 ISNULL()COALESCE() 处理NULL值
  • 日期函数注意时区和格式问题
  • 窗口函数是高级分析利器,务必掌握
  • 系统函数在运维和监控脚本中非常有用

📘 本章是SQL Server函数的百科全书,掌握后可轻松应对各种数据处理需求!

相关推荐
小高不会迪斯科5 小时前
CMU 15445学习心得(二) 内存管理及数据移动--数据库系统如何玩转内存
数据库·oracle
e***8906 小时前
MySQL 8.0版本JDBC驱动Jar包
数据库·mysql·jar
l1t6 小时前
在wsl的python 3.14.3容器中使用databend包
开发语言·数据库·python·databend
今天只学一颗糖6 小时前
1、《深入理解计算机系统》--计算机系统介绍
linux·笔记·学习·系统架构
testpassportcn6 小时前
AWS DOP-C02 認證完整解析|AWS DevOps Engineer Professional 考試
网络·学习·改行学it
失忆爆表症7 小时前
03_数据库配置指南:PostgreSQL 17 + pgvector 向量存储
数据库·postgresql
AI_56787 小时前
Excel数据透视表提速:Power Query预处理百万数据
数据库·excel
SQL必知必会8 小时前
SQL 窗口帧:ROWS vs RANGE 深度解析
数据库·sql·性能优化
Gauss松鼠会8 小时前
【GaussDB】GaussDB数据库开发设计之JDBC高可用性
数据库·数据库开发·gaussdb
+VX:Fegn08959 小时前
计算机毕业设计|基于springboot + vue鲜花商城系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计