当前位置: 首页 > news >正文

学习笔记:MYSQL(3)(常用函数和约束)

SQL中最基础、最常用的几类核心函数。以下按类别详细展开,包含函数语法、参数说明、多种示例及注意事项:

一、聚合函数(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()):截取子串

语法

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

示例

-- 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():去除空格

语法

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

示例

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

语法

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

示例

-- 统一工号格式为大写
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():获取当前时间

语法

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

示例

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

语法

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

示例

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

语法

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

示例

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

语法

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

示例

-- 计算员工入职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):简单条件判断

语法

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

示例

-- 判断员工年龄是否大于30
SELECT name,age,IF(age > 30, '大龄员工', '青年员工') AS 年龄分类
FROM emp;-- 判断性别并转换为中文
SELECT name, IF(gender = '男', '男性', '女性') AS 性别 FROM emp;
2. CASE:多条件分支判断

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

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

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

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

示例

-- 示例1:按性别分组统计(等值判断)
SELECT CASE genderWHEN '男' THEN '男性员工'WHEN '女' THEN '女性员工'ELSE '未知性别'END AS 性别分组,COUNT(*) AS 人数
FROM emp
GROUP BY gender;-- 示例2:按年龄范围分组(复杂条件)
SELECT name,age,CASEWHEN 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():取整相关

语法

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

示例

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

语法

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

示例

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

总结

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

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

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

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






----------------------------------------------分割线---------------------------------------------------------
在 SQL 中,约束(Constraint) 是用于限制表中数据的规则,确保数据的完整性、一致性和有效性。通过约束,可以避免无效数据、重复数据或不符合业务规则的数据进入表中。

常见的约束类型有以下几种:

1. 主键约束(PRIMARY KEY)

  • 作用:唯一标识表中的每条记录,确保记录不重复,且不为 NULL
  • 特点
    • 一个表只能有一个主键(可以是单个字段或多个字段组合,即联合主键)。
    • 主键字段的值必须唯一且非空。
  • 示例
    -- 单字段主键
    CREATE TABLE emp (id INT PRIMARY KEY,  -- id 作为主键name VARCHAR(50)
    );-- 联合主键(多字段组合唯一)
    CREATE TABLE student_course (student_id INT,course_id INT,score INT,PRIMARY KEY (student_id, course_id)  -- 学生ID+课程ID组合唯一
    );
    

2. 非空约束(NOT NULL)

  • 作用:限制字段的值不能为 NULL(必须填写)。
  • 示例
    CREATE TABLE emp (id INT PRIMARY KEY,name VARCHAR(50) NOT NULL,  -- 姓名不能为空age INT
    );
    
    插入数据时,如果 name 字段为空,会报错:Column 'name' cannot be null

3. 唯一约束(UNIQUE)

  • 作用:确保字段的值唯一(可以为 NULL,但 NULL 可以重复)。
  • 与主键的区别
    • 主键:唯一且非空,一个表只能有一个。
    • 唯一约束:唯一但可以为 NULL,一个表可以有多个。
  • 示例
    CREATE TABLE emp (id INT PRIMARY KEY,workno VARCHAR(10) UNIQUE,  -- 工号唯一(允许为NULL,但实际业务中通常也会加NOT NULL)name VARCHAR(50) NOT NULL
    );
    

4. 外键约束(FOREIGN KEY)

  • 作用:建立两个表之间的关联关系,确保从表(子表)的字段值必须在主表(父表)的关联字段中存在。
  • 术语
    • 主表:被引用的表(如 dept 部门表)。
    • 从表:引用主表的表(如 emp 员工表)。
    • 外键:从表中用于关联主表的字段(如 emp.dept_id)。
  • 示例
    -- 主表:部门表
    CREATE TABLE dept (dept_id INT PRIMARY KEY,dept_name VARCHAR(50) NOT NULL
    );-- 从表:员工表(含外键关联部门表)
    CREATE TABLE emp (id INT PRIMARY KEY,name VARCHAR(50) NOT NULL,dept_id INT,-- 外键约束:emp.dept_id 必须存在于 dept.dept_id 中FOREIGN KEY (dept_id) REFERENCES dept(dept_id)
    );
    
  • 效果
    • 无法在 emp 中插入 dept_id 不存在于 dept 表的值。
    • 无法删除 dept 表中已被 emp 表引用的 dept_id 记录(除非配置了级联删除)。

5. 检查约束(CHECK)

  • 作用:限制字段的值必须满足指定的条件(如年龄范围、性别只能是“男”或“女”)。
  • 示例
    CREATE TABLE emp (id INT PRIMARY KEY,name VARCHAR(50) NOT NULL,age INT CHECK (age >= 18 AND age <= 60),  -- 年龄必须在18-60之间gender VARCHAR(2) CHECK (gender IN ('男', '女'))  -- 性别只能是男或女
    );
    
    插入数据时,如果年龄为 17 或性别为“未知”,会报错。

6. 默认约束(DEFAULT)

  • 作用:为字段设置默认值,当插入数据时未指定该字段的值,自动使用默认值。
  • 示例
    CREATE TABLE emp (id INT PRIMARY KEY,name VARCHAR(50) NOT NULL,status VARCHAR(10) DEFAULT '在职',  -- 默认状态为“在职”entrydate DATE DEFAULT (CURDATE())  -- 默认入职日期为当前日期
    );-- 插入时不指定 status 和 entrydate,会自动使用默认值
    INSERT INTO emp (id, name) VALUES (1, '张三');
    

约束的添加与删除

1. 新增表时添加约束(推荐)

如上述示例,在 CREATE TABLE 语句中直接定义约束。

2. 对已有表添加约束
-- 给 emp 表的 name 字段添加非空约束
ALTER TABLE emp MODIFY name VARCHAR(50) NOT NULL;-- 给 emp 表的 workno 字段添加唯一约束
ALTER TABLE emp ADD UNIQUE (workno);-- 给 emp 表添加外键约束
ALTER TABLE emp ADD FOREIGN KEY (dept_id) REFERENCES dept(dept_id);
3. 删除约束
-- 删除唯一约束(需指定约束名,可通过 SHOW INDEX FROM 表名 查看)
ALTER TABLE emp DROP INDEX workno;-- 删除外键约束(需指定外键名)
ALTER TABLE emp DROP FOREIGN KEY emp_ibfk_1;  -- 外键名通常为系统自动生成-- 删除非空约束(改为允许 NULL)
ALTER TABLE emp MODIFY name VARCHAR(50) NULL;

总结

约束是保证数据质量的重要手段,不同约束的适用场景:

  • 主键:唯一标识记录(如 id)。
  • 非空:确保必填字段(如 name)。
  • 唯一:确保字段值不重复(如 worknoemail)。
  • 外键:维护表之间的关联关系(如员工与部门)。
  • 检查:限制字段值的范围(如年龄、性别)。
  • 默认:简化常用值的插入(如默认状态、当前日期)。

合理使用约束可以减少程序中的数据校验逻辑,降低数据错误的风险。


文章转载自:

http://cjxAMy73.yhywx.cn
http://URwmJFTJ.yhywx.cn
http://plvvOM7O.yhywx.cn
http://bbtZefnU.yhywx.cn
http://SuUMo2B9.yhywx.cn
http://ForOdkvP.yhywx.cn
http://51YdySEv.yhywx.cn
http://dcVXPPlD.yhywx.cn
http://kvkWNbmq.yhywx.cn
http://dpn9oxBl.yhywx.cn
http://ppgof54b.yhywx.cn
http://65vMYaO1.yhywx.cn
http://aoh5584U.yhywx.cn
http://fPCRyHfx.yhywx.cn
http://KFvlwtUT.yhywx.cn
http://5otL5BjF.yhywx.cn
http://EWjlX5T5.yhywx.cn
http://Vatqe9rM.yhywx.cn
http://E3LG6rmF.yhywx.cn
http://Ns7jxyQ8.yhywx.cn
http://6T7afMUC.yhywx.cn
http://8aF8DJLg.yhywx.cn
http://KOgXnkTl.yhywx.cn
http://LKfsbSDB.yhywx.cn
http://F0pKeUo7.yhywx.cn
http://p9bTYcaT.yhywx.cn
http://8Jucppks.yhywx.cn
http://KUHdp0v8.yhywx.cn
http://RkhjrsCk.yhywx.cn
http://lthNIoDV.yhywx.cn
http://www.dtcms.com/a/364466.html

相关文章:

  • dvs dvfs avs avfs 低功耗技术的区别
  • DBSCAN 密度聚类分析算法
  • 第二章:技术基石:写出“活”的代码(2)
  • DVWA靶场通关笔记-存储型XSS(Stored Impossible级别)
  • K8s Pod CrashLoopBackOff:从镜像构建到探针配置的排查过程
  • AI Agent重构SOC:下一代智能安全运营平台的能力跃迁
  • 解析SWOT分析和PV/UV这两个在产品与运营领域至关重要的知识点。
  • 【LeetCode 热题 100】72. 编辑距离——(解法一)记忆化搜索
  • 【LM358AD差分检测电压差】2022-11-30
  • 刻意练习理论
  • C++ 多线程编程
  • 【IO】进程间通信(IPC)练习
  • CAD/BIM软件产品技术深度分析文章写作计划
  • 7.4Element Plus 分页与表格组件
  • java spring cloud 企业工程管理系统源码+二次开发+定制化服务
  • 深兰科技AI问诊助手走访打浦桥街道社区卫生服务中心
  • Llama.cpp与CUDA Graph:深度学习推理框架的兼容性深度解析
  • Elasticsearch(text和keyword)区别分析
  • 怎么删除word空白页?【图文详解】删除最后一页空白页?5种删除word文档空白页方法?
  • Few-Shot Prompting 实战:用5个例子让GPT-4学会复杂任务
  • 线程与同步
  • 【Unity Shader学习笔记】(四)Shader编程
  • Java设计模式之结构型—适配器模式
  • SQLAlchemy ORM 入门教程
  • Low-Light Image Enhancement via Structure Modeling and Guidance 论文阅读
  • SQLint3 模块如何使用
  • Linux awk命令完全指南:从原理到实战,搞定文本处理难题
  • SQL(window)日志在linux 下查看
  • LangChain实战(十三):Agent Types详解与选择策略
  • 机器学习从入门到精通 - KNN与SVM实战指南:高维空间中的分类奥秘