学习笔记:MYSQL(3)

发布于:2025-09-13 ⋅ 阅读:(13) ⋅ 点赞:(0)

一、聚合函数(Aggregate Functions)

核心特点:对一组数据(列)进行计算,返回单一结果,常与GROUP BY配合,也可单独用于整表统计。

1. COUNT():统计记录数量

语法

COUNT(*)  -- 统计所有记录(包括NULL值、重复值)
COUNT(字段名)  -- 统计该字段非NULL值的记录数
COUNT(DISTINCT 字段名)  -- 统计该字段非NULL且去重后的记录数

示例(基于emp表):

-- 1. 统计员工总人数(包括所有记录,即使字段有NULL)
SELECT COUNT(*) AS 总人数 FROM emp;  -- 结果:35(假设35条数据)

-- 2. 统计有年龄记录的员工数(排除age为NULL的记录)
SELECT COUNT(age) AS 有年龄记录的人数 FROM emp;  -- 结果:35(假设age无NULL)

-- 3. 统计不同性别的人数(去重统计)
SELECT COUNT(DISTINCT gender) AS 性别种类数 FROM emp;  -- 结果:2(男/女)

注意COUNT(*)效率通常高于COUNT(字段名),因为前者不判断字段是否为 NULL。

2. SUM():计算数值总和

语法

SUM(字段名)  -- 计算该字段所有非NULL值的总和
SUM(DISTINCT 字段名)  -- 计算该字段去重后非NULL值的总和
-- 1. 计算所有员工年龄总和
SELECT SUM(age) AS 年龄总和 FROM emp;  -- 结果:假设总和为980

-- 2. 计算不同年龄的总和(去重后)
SELECT SUM(DISTINCT age) AS 去重年龄总和 FROM emp;  -- 结果:假设去重后年龄和为350

注意:仅适用于数值类型字段(int/float等),字符串或日期字段使用会报错。

3. AVG():计算平均值

语法

AVG(字段名)  -- 计算该字段非NULL值的平均值(总和/非NULL记录数)
AVG(DISTINCT 字段名)  -- 计算去重后非NULL值的平均值

示例

-- 1. 计算所有员工的平均年龄
SELECT AVG(age) AS 平均年龄 FROM emp;  -- 结果:980/35=28

-- 2. 计算不同年龄的平均值(去重后)
SELECT AVG(DISTINCT age) AS 去重年龄平均值 FROM emp;  -- 结果:350/去重年龄数量

注意:计算时会自动排除 NULL 值,例如 10 条记录中 2 条age为 NULL,则按 8 条计算。

4. MAX()/MIN():最大值 / 最小值

语法

MAX(字段名)  -- 返回该字段非NULL值中的最大值
MIN(字段名)  -- 返回该字段非NULL值中的最小值

适用字段类型

  • 数值型(int/float):比较大小
  • 字符串型(varchar):按字符编码顺序(如'a' < 'b'
  • 日期型(date):按时间先后(如'2020-01-01' < '2023-01-01'

示例

-- 1. 数值型:最大/最小年龄
SELECT MAX(age) AS 最大年龄, MIN(age) AS 最小年龄 FROM emp;  -- 结果:33, 23

-- 2. 日期型:最新/最早入职日期
SELECT MAX(entrydate) AS 最新入职, MIN(entrydate) AS 最早入职 FROM emp;  -- 结果:2022-05-12, 2017-05-02

-- 3. 字符串型:按姓名排序的最大/最小值(按拼音首字母)
SELECT MAX(name) AS 姓名最大值, MIN(name) AS 姓名最小值 FROM emp;  -- 结果:如'郑十', '白一'(假设存在)

二、字符串函数(String Functions)

核心特点:处理字符串类型字段(char/varchar),包括拼接、截取、转换等操作。

1. CONCAT()/CONCAT_WS():字符串拼接

语法

CONCAT(str1, str2, ...)  -- 拼接多个字符串,若任何一个为NULL,结果为NULL
CONCAT_WS(分隔符, str1, str2, ...)  -- 用指定分隔符拼接,忽略NULL值

示例

-- 1. 拼接姓名和性别(无分隔符)
SELECT CONCAT(name, '(', gender, ')') AS 姓名性别 FROM emp;  -- 结果:'张三(男)'

-- 2. 用逗号分隔拼接多个字段(忽略NULL)
SELECT CONCAT_WS(',', name, workno, age) AS 员工信息 FROM emp;  -- 结果:'张三,W001,25'

注意CONCAT_WS中 “WS” 是 “With Separator” 的缩写,适合拼接带分隔符的字符串(如地址、联系方式)。

2. SUBSTRING()(别名SUBSTR()):截取子串

语法

sql

SUBSTRING(str, pos, len)  -- 从str的pos位置开始,截取len长度的子串
-- pos:起始位置(正数从左数,负数从右数);len:可选,默认截取到末尾

示例

sql

-- 1. 截取身份证号前6位(地址码)
SELECT idcard, SUBSTRING(idcard, 1, 6) AS 地址码 FROM emp;  -- 结果:'1101011998...' → '110101'

-- 2. 截取姓名最后1个字符(从右数第1位)
SELECT name, SUBSTRING(name, -1) AS 姓名尾字 FROM emp;  -- 结果:'张三' → '三'

-- 3. 从第3位开始截取到末尾
SELECT SUBSTRING('HelloWorld', 3) AS 子串;  -- 结果:'lloWorld'
3. TRIM()/LTRIM()/RTRIM():去除空格

语法

sql

TRIM(str)  -- 去除str首尾空格
LTRIM(str)  -- 去除str左侧(开头)空格
RTRIM(str)  -- 去除str右侧(结尾)空格

示例

sql

-- 处理带空格的姓名
SELECT 
  name AS 原姓名,
  TRIM(name) AS 去除首尾空格,
  LTRIM(name) AS 去除左空格,
  RTRIM(name) AS 去除右空格
FROM emp WHERE name LIKE ' %' OR name LIKE '% ';  -- 筛选带空格的姓名
4. UPPER()/LOWER():大小写转换

语法

sql

UPPER(str)  -- 将字符串转为大写
LOWER(str)  -- 将字符串转为小写

示例

sql

-- 统一工号格式为大写
SELECT workno, UPPER(workno) AS 大写工号 FROM emp;  -- 结果:'w001' → 'W001'

-- 统一邮箱格式为小写(假设表中有email字段)
SELECT email, LOWER(email) AS 小写邮箱 FROM user;  -- 结果:'ZhangSan@XX.com' → 'zhangsan@xx.com'

注意:对中文、数字无效,仅影响英文字母。

三、日期函数(Date Functions)

核心特点:处理日期时间类型(date/datetime/timestamp),用于提取日期部分、计算时间差等。

1. NOW()/CURDATE()/CURTIME():获取当前时间

语法

sql

NOW()  -- 返回当前日期时间(格式:YYYY-MM-DD HH:MM:SS)
CURDATE()  -- 返回当前日期(格式:YYYY-MM-DD)
CURTIME()  -- 返回当前时间(格式:HH:MM:SS)

示例

sql

SELECT 
  NOW() AS 当前日期时间,
  CURDATE() AS 当前日期,
  CURTIME() AS 当前时间;
-- 结果:
-- 2023-10-01 15:30:45 | 2023-10-01 | 15:30:45
2. YEAR()/MONTH()/DAY():提取日期部分

语法

sql

YEAR(date)  -- 提取年份
MONTH(date)  -- 提取月份(1-12)
DAY(date)  -- 提取日(1-31)
HOUR(time)  -- 提取小时(0-23)
MINUTE(time)  -- 提取分钟(0-59)
SECOND(time)  -- 提取秒(0-59)

示例

sql

-- 分析员工入职年份分布
SELECT 
  entrydate AS 入职日期,
  YEAR(entrydate) AS 入职年份,
  MONTH(entrydate) AS 入职月份
FROM emp;
3. DATEDIFF():计算日期差

语法

sql

DATEDIFF(date1, date2)  -- 返回date1 - date2的天数(正数表示date1晚于date2)

示例

sql

-- 计算员工入职至今的天数
SELECT 
  name,
  entrydate AS 入职日期,
  DATEDIFF(CURDATE(), entrydate) AS 入职天数
FROM emp;
4. DATE_ADD()/DATE_SUB():日期增减

语法

sql

DATE_ADD(date, INTERVAL 数值 单位)  -- 日期加指定间隔
DATE_SUB(date, INTERVAL 数值 单位)  -- 日期减指定间隔
-- 单位:DAY(天)、MONTH(月)、YEAR(年)、HOUR(小时)等

示例

sql

-- 计算员工入职3年后的日期
SELECT 
  name,
  entrydate AS 入职日期,
  DATE_ADD(entrydate, INTERVAL 3 YEAR) AS 入职3年后
FROM emp;

-- 计算10天前的日期
SELECT DATE_SUB(CURDATE(), INTERVAL 10 DAY) AS 10天前;  -- 结果:2023-09-21(假设当前是2023-10-01)

四、条件函数(Conditional Functions)

核心特点:根据条件返回不同结果,类似编程语言中的if-else逻辑。

1. IF(condition, val_true, val_false):简单条件判断

语法

sql

IF(条件表达式, 条件为真时返回值, 条件为假时返回值)

示例

sql

-- 判断员工年龄是否大于30
SELECT 
  name,
  age,
  IF(age > 30, '大龄员工', '青年员工') AS 年龄分类
FROM emp;

-- 判断性别并转换为中文
SELECT name, IF(gender = '男', '男性', '女性') AS 性别 FROM emp;
2. CASE:多条件分支判断

语法 1:简单等值判断(类似switch-case

sql

CASE 字段名
  WHEN 值1 THEN 结果1
  WHEN 值2 THEN 结果2
  ...
  ELSE 默认结果  -- 可选,所有条件不满足时返回
END

语法 2:复杂条件判断(类似if-else if-else

sql

CASE
  WHEN 条件1 THEN 结果1
  WHEN 条件2 THEN 结果2
  ...
  ELSE 默认结果  -- 可选
END

示例

sql

-- 示例1:按性别分组统计(等值判断)
SELECT 
  CASE gender
    WHEN '男' THEN '男性员工'
    WHEN '女' THEN '女性员工'
    ELSE '未知性别'
  END AS 性别分组,
  COUNT(*) AS 人数
FROM emp
GROUP BY gender;

-- 示例2:按年龄范围分组(复杂条件)
SELECT 
  name,
  age,
  CASE
    WHEN age < 25 THEN '25岁以下'
    WHEN age BETWEEN 25 AND 30 THEN '25-30岁'
    WHEN age > 30 THEN '30岁以上'
    ELSE '年龄未知'
  END AS 年龄范围
FROM emp;

五、数值函数(Numeric Functions)

核心特点:处理数值类型数据,包括取整、四舍五入、计算绝对值等。

1. ROUND()/CEIL()/FLOOR():取整相关

语法

sql

ROUND(num, 小数位数)  -- 四舍五入(默认保留0位小数)
CEIL(num)  -- 向上取整(返回≥num的最小整数)
FLOOR(num)  -- 向下取整(返回≤num的最大整数)

示例

sql

SELECT 
  ROUND(3.1415, 2) AS 四舍五入2位,  -- 结果:3.14
  ROUND(3.5) AS 四舍五入整数,       -- 结果:4
  CEIL(3.2) AS 向上取整,            -- 结果:4
  FLOOR(3.8) AS 向下取整;           -- 结果:3
2. ABS()/MOD():绝对值与取模

语法

sql

ABS(num)  -- 取绝对值
MOD(num1, num2)  -- 取模(num1除以num2的余数,同 num1 % num2)

示例

sql

SELECT 
  ABS(-100) AS 绝对值,  -- 结果:100
  MOD(7, 3) AS 取模,    -- 结果:1(7÷3=2余1)
  MOD(10, 2) AS 偶数判断;  -- 结果:0(10是偶数)

总结

这些基础函数是 SQL 查询的 “积木”,灵活组合可实现复杂的数据处理需求:

  • 聚合函数 + GROUP BY:用于统计分析(如各部门人数、平均工资);
  • 字符串函数:处理格式清洗(如手机号脱敏、姓名拼接);
  • 日期函数:计算时间差(如用户活跃天数、合同到期提醒);
  • 条件函数:实现数据分类(如等级划分、状态转换)。

实际使用时,可通过SELECT 函数(参数)直接测试函数效果(无需从表中查询),例如:

sql

SELECT CONCAT('Hello', 'SQL'), DATEDIFF('2023-12-31', CURDATE());