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

MySQL(四) - 数据查询操作

文章目录

  • 一、准备数据
    • 1. 重新创建之前的三个表
    • 2. 分别向三个表中插入数据
  • 二、查询语法、运算符和函数
    • 1. 语法及解释
    • 2. 条件查询运算符
    • 3. 函数
  • 三、数据查询
    • 1. 简单查询
      • 1.1 查询表中全部数据
      • 1.2 查询表中指定字段的数据
      • 1.3 查询表中指定字段的数据并起别名
      • 1.4 查询表中指定字段不重复的数据
      • 1.5 查询表中前10条数据
    • 2. 条件查询
      • 2.1 比较运算符查询
        • 2.1.1 查询表中分数大于90的数据
        • 2.1.1 查询表中选课无效的数据
      • 2.2 范围运算符查询
        • 2.2.1 查询表中分数大于等于80且小于等于90的数据
        • 2.2.2 查询表中分数不是大于等于80且小于等于90的数据
      • 2.3 空值判断运算符查询
        • 2.3.1 查询表中分数为空的数据
        • 2.3.2 查询表中分数不为空的数据
      • 2.4 逻辑运算符查询
        • 2.4.1 查询表中分数大于等于80且小于等于90的数据
        • 2.4.2 查询表中专业是数学或计科的数据
        • 2.4.3 查询表中专业不是数学或计科的数据
      • 2.5 集合运算符查询
        • 2.5.1 查询表中专业是数学或计科的数据
        • 2.5.2 查询表中专业不是数学或计科的数据
      • 2.6 模式匹配运算符查询
        • 2.6.1 查询表中姓吴的同学的数据
        • 2.6.2 查询表中姓名包含娟字的同学的数据
        • 2.6.3 查询表中专业为两个字且第二个字为学的数据
    • 3. 函数查询
      • 3.1 聚合函数查询
        • 3.1.1 查询表中的最高分和最低分
        • 3.1.2 查询指定学生的总分和平均分
        • 3.1.3 查询指定学生所选课程数
        • 3.1.4 查询指定表数据量
    • 4. 分组、排序和限制查询
      • 4.1 查询每个专业的学生人数
      • 4.2 查询每个专业的学生人数并筛选
      • 4.3 按学号升序查询
      • 4.4 按学号降序查询
      • 4.5 按学号升序查询并限制返回20条数据


一、准备数据

1. 重新创建之前的三个表

该部分代码用于在test001数据库中重新创建学生表(student)、课程表(course)和学生课程关系表(student_course),并为各表设置了主键、唯一约束、外键约束及检查约束等,确保数据的完整性和规范性,同时指定了存储引擎、字符集等表属性。

-- 创建数据库
CREATE DATABASE IF NOT EXISTS test001;
-- 切换数据库
USE test001;
-- 删除数据表
DROP TABLE IF EXISTS student_course;
DROP TABLE IF EXISTS student;
DROP TABLE IF EXISTS course;-- 1. 学生表(主表)
CREATE TABLE IF NOT EXISTS `student` (student_id INT NOT NULL AUTO_INCREMENT COMMENT '学生ID(主键)',student_no VARCHAR(20) NOT NULL COMMENT '学号(唯一标识,如2024001)',student_name VARCHAR(50) NOT NULL COMMENT '学生姓名',gender CHAR(1) NOT NULL COMMENT '性别(男/女)',birth_date DATE NULL COMMENT '出生日期',major VARCHAR(50) NOT NULL COMMENT '所属专业',enroll_date DATE NOT NULL COMMENT '入学时间',create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '记录创建时间',-- 列级约束PRIMARY KEY (student_id),UNIQUE KEY uk_student_no (student_no),  -- 学号唯一CHECK (gender IN ('男', '女'))  -- 限制性别只能是男或女
)
ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci
AUTO_INCREMENT = 1001  -- 学生ID从1001开始
COMMENT = '学生信息表';
-- 2. 课程表(主表)
CREATE TABLE IF NOT EXISTS `course` (course_id INT NOT NULL AUTO_INCREMENT COMMENT '课程ID(主键)',course_no VARCHAR(20) NOT NULL COMMENT '课程编号(如CS101)',course_name VARCHAR(100) NOT NULL COMMENT '课程名称',credit TINYINT NOT NULL COMMENT '学分(1-6分)',teacher_name VARCHAR(50) NOT NULL COMMENT '授课教师',course_hours INT NOT NULL COMMENT '课时数',create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '记录创建时间',-- 列级约束PRIMARY KEY (course_id),UNIQUE KEY uk_course_no (course_no),  -- 课程编号唯一CHECK (credit BETWEEN 1 AND 6),  -- 学分范围限制CHECK (course_hours > 0)  -- 课时必须为正数
)
ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci
AUTO_INCREMENT = 101  -- 课程ID从101开始
COMMENT = '课程信息表';
-- 3. 选课表(关系表,关联学生表和课程表)
CREATE TABLE IF NOT EXISTS `student_course` (id INT NOT NULL AUTO_INCREMENT COMMENT '选课记录ID(主键)',student_id INT NOT NULL COMMENT '学生ID(外键关联学生表)',course_id INT NOT NULL COMMENT '课程ID(外键关联课程表)',select_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '选课时间',score DECIMAL(5,2) NULL COMMENT '课程成绩(0-100分,NULL表示未考试)',is_valid TINYINT NOT NULL DEFAULT 1 COMMENT '是否有效(1-有效,0-已退课)',-- 表级约束PRIMARY KEY (id),-- 联合唯一约束:同一学生不能重复选同一门课UNIQUE KEY uk_stu_course (student_id, course_id),-- 外键约束:关联学生表CONSTRAINT fk_sc_student FOREIGN KEY (student_id)REFERENCES `student`(student_id)ON DELETE CASCADE  -- 学生记录删除时,关联的选课记录自动删除ON UPDATE CASCADE,  -- 学生ID更新时,选课记录同步更新-- 外键约束:关联课程表CONSTRAINT fk_sc_course FOREIGN KEY (course_id)REFERENCES `course`(course_id)ON DELETE CASCADE  -- 课程记录删除时,关联的选课记录自动删除ON UPDATE CASCADE,-- 检查约束:成绩范围限制(0-100分)CONSTRAINT chk_score CHECK (score IS NULL OR (score BETWEEN 0 AND 100)),-- 检查约束:is_valid只能是0或1CONSTRAINT chk_is_valid CHECK (is_valid IN (0, 1))
)
ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_general_ci
COMMENT = '学生选课关系表';

2. 分别向三个表中插入数据

此部分通过存储过程向上述三个表中批量插入示例数据,为后续的数据查询操作提供基础。

使用存储过程InsertStudentsstudent表插入 500 条学生数据,包括学号、姓名、性别、出生日期、专业、入学时间等信息,数据通过随机方式生成,模拟真实学生信息。

-- 插入 500 条学生数据
DELIMITER $$
CREATE PROCEDURE InsertStudents()
BEGINDECLARE i INT DEFAULT 1;DECLARE gender CHAR(1);DECLARE year_start DATE;DECLARE birth DATE;DECLARE major_name VARCHAR(50);-- 常见专业列表SET @majors = '计算机科学与技术,软件工程,电子信息工程,数学与应用数学,物理学,化学,生物技术,机械工程,自动化,通信工程,''土木工程,环境工程,经济学,金融学,会计学,法学,汉语言文学,英语,新闻传播学,临床医学,护理学';WHILE i <= 500 DOSET gender = IF(RAND() > 0.5, '男', '女');-- 随机入学年份:2020 - 2024SET year_start = MAKEDATE(2020 + FLOOR(RAND() * 5), 1 + FLOOR(RAND() * 365));-- 出生日期:入学时 17~23 岁SET birth = DATE_SUB(year_start, INTERVAL FLOOR(17 + RAND() * 7) YEAR);-- 随机选择专业SET major_name = ELT(CEILING(RAND() * 21), '计算机科学与技术','软件工程','电子信息工程','数学与应用数学','物理学','化学','生物技术','机械工程','自动化','通信工程','土木工程','环境工程','经济学','金融学','会计学','法学','汉语言文学','英语','新闻传播学','临床医学','护理学');INSERT INTO `student` (student_no, student_name, gender, birth_date, major, enroll_date)VALUES (CONCAT('20', LPAD(FLOOR(RAND() * 90 + 24), 2, '0'), LPAD(i, 3, '0')),  -- 如 2024001CONCAT(ELT(CEILING(RAND() * 10), '张','李','王','刘','陈','杨','黄','赵','周','吴'),ELT(CEILING(RAND() * 10), '伟','芳','敏','静','勇','磊','洋','娟','强','军')),gender,birth,major_name,year_start);SET i = i + 1;END WHILE;
END$$
DELIMITER ;-- 执行并清理
CALL InsertStudents();
DROP PROCEDURE IF EXISTS InsertStudents;

使用存储过程InsertCoursescourse表插入 500 条课程数据,涵盖课程编号、名称、学分、授课教师、课时数等内容,同样通过随机方式生成,模拟实际课程信息。

-- 插入 500 条课程数据
DELIMITER $$
CREATE PROCEDURE InsertCourses()
BEGINDECLARE i INT DEFAULT 1;DECLARE course_name_prefix VARCHAR(50);DECLARE teacher_name VARCHAR(50);SET @prefixes = '高等数学,线性代数,概率统计,C语言程序设计,Java编程,Python数据分析,数据结构,算法设计,操作系统,''计算机网络,数据库原理,软件工程,电路分析,模拟电子技术,数字逻辑,信号与系统,电磁场与波,自动控制原理,''大学物理,大学化学,马克思主义基本原理,中国近代史纲要,英语读写,体育健康,艺术鉴赏,心理学导论,经济学基础';WHILE i <= 500 DOSET course_name_prefix = ELT(CEILING(RAND() * 27),'高等数学','线性代数','概率统计','C语言程序设计','Java编程','Python数据分析','数据结构','算法设计','操作系统','计算机网络','数据库原理','软件工程','电路分析','模拟电子技术','数字逻辑','信号与系统','电磁场与波','自动控制原理','大学物理','大学化学','马克思主义基本原理','中国近代史纲要','英语读写','体育健康','艺术鉴赏','心理学导论','经济学基础');SET teacher_name = CONCAT(ELT(CEILING(RAND() * 10), '张','李','王','刘','陈','杨','黄','赵','周','吴'),'老师');INSERT INTO `course` (course_no, course_name, credit, teacher_name, course_hours)VALUES (CONCAT('CS', LPAD(i, 3, '0')),  -- CS001, CS002...CONCAT(course_name_prefix, '(', CEILING(RAND() * 10), '期)'),CEILING(RAND() * 6),  -- 1~6 学分teacher_name,CASE CEILING(RAND() * 5)WHEN 1 THEN 32WHEN 2 THEN 48WHEN 3 THEN 64WHEN 4 THEN 80ELSE 96END);SET i = i + 1;END WHILE;
END$$
DELIMITER ;-- 执行并清理
CALL InsertCourses();
DROP PROCEDURE IF EXISTS InsertCourses;

使用存储过程InsertStudentCoursestudent_course表插入 500 条不重复的选课记录,包含学生 ID、课程 ID、选课时间、成绩、是否有效等信息,随机生成以模拟学生选课情况。

-- 插入 500 条不重复的选课记录
DELIMITER $$
CREATE PROCEDURE InsertStudentCourse()
BEGINDECLARE i INT DEFAULT 1;DECLARE sid INT;DECLARE cid INT;DECLARE retry_count INT DEFAULT 0;DECLARE max_retries INT DEFAULT 2000;WHILE i <= 500 DO-- 随机学生ID:1001 ~ 1500SET sid = FLOOR(1001 + RAND() * 500);-- 随机课程ID:101 ~ 600SET cid = FLOOR(101 + RAND() * 500);-- 尝试插入,跳过已存在的组合BEGINDECLARE CONTINUE HANDLER FOR 1062 BEGIN END; -- 忽略重复键错误INSERT INTO `student_course` (student_id, course_id, select_time, score, is_valid)VALUES (sid,cid,NOW() - INTERVAL FLOOR(RAND() * 365) DAY,  -- 近一年内选课IF(RAND() > 0.2, ROUND(40 + RAND() * 60, 2), NULL), -- 80% 有成绩IF(RAND() > 0.1, 1, 0) -- 90% 有效,10% 已退课);-- 成功插入才计数SET i = i + 1;END;SET retry_count = retry_count + 1;IF retry_count > max_retries THENSIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '插入失败:可能可用的 (student_id, course_id) 组合已耗尽';END IF;END WHILE;
END$$
DELIMITER ;-- 执行并清理
CALL InsertStudentCourse();
DROP PROCEDURE IF EXISTS InsertStudentCourse;

检查数据数量是否正确,该 SQL 语句用于查询studentcoursestudent_course三个表中的数据条数,以验证各表数据插入数量是否符合预期。

-- 检查每张表的数据量
SELECT 'student' AS table_name, COUNT(*) AS count FROM student
UNION ALL
SELECT 'course' AS table_name, COUNT(*) AS count FROM course
UNION ALL
SELECT 'student_course' AS table_name, COUNT(*) AS count FROM student_course;

二、查询语法、运算符和函数

1. 语法及解释

该部分详细拆解 MySQL 基础查询语句的完整结构,对 SELECT 到 LIMIT 的每个子句进行定义,明确各子句的必填 / 可选属性、核心功能及使用规则,同时标注关键注意事项(如 WHERE 子句使用函数对索引的影响),帮助理解各子句在查询流程中的作用和执行顺序。

SELECT [ALL | DISTINCT] <字段名> [AS 别名] [, <字段名> [AS 别名]] ...
FROM <表名或者视图名> [AS 表别名]
[WHERE <检索条件>]
[GROUP BY <字段名> [HAVING <条件表达式>>]]
[ORDER BY <字段名> [ASC | DESC]]
[LIMIT 子句];
  • SELECT: 查询语句的必选起始关键字,用于指定要从数据库中检索哪些数据。

    • [ALL | DISTINCT]: 可选的修饰符。
      • ALL: 返回所有匹配的行,包括重复的行。这是默认行为。
      • DISTINCT: 去除结果集中完全相同的重复行,只返回唯一的结果。
    • <字段名>: 指定要查询的具体列名。可以查询一个或多个列。
    • [AS 别名]: 可选的列别名。为查询出的列指定一个临时的、更易读或更简短的名称。AS 关键字通常可以省略,直接写 字段名 别名
  • FROM: 查询语句的必选关键字,用于指定数据的来源。

    • <表名或者视图名>: 指明数据来自哪个数据库表或视图。
    • [AS 表别名]: 可选的表别名。为表或视图指定一个临时的简称,在查询(尤其是多表连接)中可以简化书写和引用。
  • [WHERE <检索条件>]: 可选子句,用于对数据行进行筛选

    • <检索条件>: 一个布尔表达式,只有满足此条件的行才会被包含在结果集中。它在分组 (GROUP BY) 之前执行。常用操作符包括:=<>/!=<><=>=INBETWEEN ... AND ...LIKEIS NULL 以及逻辑运算符 ANDORNOT
    • 注意:WHERE中一般不建议使用函数,在WHERE中使用函数会使索引失效。
  • [GROUP BY <字段名>]: 可选子句,用于将结果集中的行根据一个或多个列的值进行分组

    • <字段名>: 用于分组的列名。通常与聚合函数(如 COUNT()SUM()AVG()MAX()MIN())结合使用,以对每个分组进行统计计算。在 SELECT 子句中出现的非聚合函数字段,通常也必须出现在 GROUP BY 子句中。
  • [HAVING <条件表达式>]: 可选子句,用于对分组后的结果进行筛选

    • <条件表达式>: 一个布尔表达式,但与 WHERE 不同,HAVING 可以引用聚合函数(如 COUNT(*) > 1, SUM(salary) < 10000)。它在分组 (GROUP BY) 之后执行,用于过滤分组。
  • [ORDER BY <字段名> [ASC | DESC]]: 可选子句,用于对最终的查询结果集进行排序

    • <字段名>: 指定排序所依据的列。
    • [ASC | DESC]: 指定排序方式。ASC 表示升序(从小到大),DESC 表示降序(从大到小)。默认为 ASC。可以按多个字段排序,用逗号分隔。
  • [LIMIT 子句]: 可选子句,用于限制返回结果的行数。

    • 这对于分页显示数据非常有用。常见格式有:
      • LIMIT N: 返回结果集的前 N 行。
      • LIMIT M, NLIMIT N OFFSET M: 跳过前 M 行,返回接下来的 N 行。

2. 条件查询运算符

此处以表格形式分类整理 MySQL 常用条件查询运算符,涵盖比较、范围、集合、模式匹配、空值判断、逻辑 6 大类别,每个运算符均搭配语法示例和功能说明,清晰展示不同运算符的使用场景和判断逻辑,为编写筛选条件提供直观参考。

运算符类别运算符语法示例说明
比较运算符=WHERE age = 25等于。检查两个值是否相等。
<>!=WHERE status <> 'inactive'不等于。检查两个值是否不相等。
<WHERE price < 100小于。检查左边的值是否小于右边的值。
>WHERE score > 90大于。检查左边的值是否大于右边的值。
<=WHERE quantity <= 5小于或等于。
>=WHERE salary >= 5000大于或等于。
<=>WHERE column <=> NULL安全等于。与 = 类似,但可以正确比较 NULL 值(NULL <=> NULL 返回 TRUE)。
范围运算符BETWEEN ... AND ...WHERE age BETWEEN 18 AND 60在指定范围内。包含边界值,等价于 >=<= 的组合。
NOT BETWEEN ... AND ...WHERE price NOT BETWEEN 10 AND 50不在指定范围内。
集合运算符INWHERE city IN ('Beijing', 'Shanghai', 'Guangzhou')在给定的值列表中。如果字段值匹配列表中的任何一个,则返回 TRUE
NOT INWHERE status NOT IN ('deleted', 'blocked')不在给定的值列表中。
模式匹配运算符LIKEWHERE name LIKE 'Li%'模糊匹配字符串。
- % 代表零个、一个或多个任意字符。
- _ 代表一个任意字符。
NOT LIKEWHERE email NOT LIKE '%@qq.com'不匹配指定的模式。
REGEXP / RLIKEWHERE phone REGEXP '^1[3-9][0-9]{9}$'使用正则表达式进行更复杂的模式匹配。
NOT REGEXP / NOT RLIKEWHERE content NOT REGEXP 'spam'不匹配指定的正则表达式。
空值判断运算符IS NULLWHERE end_date IS NULL判断字段值是否为 NULL。注意:不能用 = NULL 来判断!
IS NOT NULLWHERE email IS NOT NULL判断字段值是否不为 NULL
逻辑运算符ANDWHERE age > 18 AND city = 'Beijing'逻辑与。只有当所有条件都为 TRUE 时,结果才为 TRUE
ORWHERE department = 'IT' OR department = 'HR'逻辑或。只要有一个条件为 TRUE,结果就为 TRUE
NOTWHERE NOT (status = 'inactive')逻辑非。将条件的结果取反。

3. 函数

此处按功能类别(字符串、数值、日期和时间、条件、聚合、加密与哈希、系统与信息)梳理 MySQL 常用函数,每个函数均包含语法示例和详细说明,明确函数的参数要求、返回结果及使用场景,覆盖数据处理、计算、格式化、统计等各类需求,方便查询时按需选用。

类别函数语法示例说明
字符串函数CONCAT(str1,str2,...)SELECT CONCAT(first_name, ' ', last_name) FROM users;将多个字符串连接成一个字符串。
CONCAT_WS(separator, str1,str2,...)SELECT CONCAT_WS('-', '2025', '10', '21');使用指定的分隔符连接字符串。WS 意为 “With Separator”。
UPPER(str) / UCASE(str)SELECT UPPER('hello'); -- HELLO将字符串转换为大写。
LOWER(str) / LCASE(str)SELECT LOWER('WORLD'); -- world将字符串转换为小写。
LENGTH(str)SELECT LENGTH('MySQL'); -- 6返回字符串的字节长度。注意:对于多字节字符(如中文),一个字符可能占多个字节。
CHAR_LENGTH(str)SELECT CHAR_LENGTH('你好'); -- 2返回字符串的字符长度。
SUBSTRING(str, pos, len)
SUBSTR()
MID()
SELECT SUBSTRING('MySQL', 2, 3); -- ySQ从字符串 str 的第 pos 个字符开始,截取长度为 len 的子串。位置从 1 开始。
LEFT(str, len) / RIGHT(str, len)SELECT LEFT('MySQL', 3); -- MyS分别返回字符串左边/右边的 len 个字符。
TRIM(str)SELECT TRIM(' MySQL '); -- MySQL移除字符串首尾的空格。
LTRIM(str) / RTRIM(str)SELECT LTRIM(' MySQL'); -- MySQL分别移除字符串左边/右边的空格。
REPLACE(str, from_str, to_str)SELECT REPLACE('hello world', 'world', 'MySQL');将字符串中的 from_str 替换为 to_str
REVERSE(str)SELECT REVERSE('abc'); -- cba反转字符串。
INSTR(str, substr)SELECT INSTR('MySQL', 'SQL'); -- 3返回子串 substr 在字符串 str 中第一次出现的位置(从1开始)。未找到返回0。
LOCATE(substr, str, pos)SELECT LOCATE('SQL', 'MySQL', 2); -- 3INSTR 类似,但可以指定搜索的起始位置 pos
FORMAT(X, D)SELECT FORMAT(1234567.89, 2); -- 1,234,567.89将数字 X 格式化为带有千位分隔符的字符串,保留 D 位小数。
数值函数ABS(X)SELECT ABS(-5); -- 5返回 X 的绝对值。
CEIL(X) / CEILING(X)SELECT CEIL(3.2); -- 4返回不小于 X 的最小整数(向上取整)。
FLOOR(X)SELECT FLOOR(3.8); -- 3返回不大于 X 的最大整数(向下取整)。
ROUND(X, D)SELECT ROUND(3.14159, 2); -- 3.14X 四舍五入到 D 位小数。D 可省略,默认为0。
TRUNCATE(X, D)SELECT TRUNCATE(3.14159, 3); -- 3.141X 截断到 D 位小数(直接舍去,不四舍五入)。
MOD(N, M) / N % MSELECT MOD(10, 3); -- 1返回 N 除以 M 的余数。
POWER(X, Y) / POW(X, Y)SELECT POWER(2, 3); -- 8返回 XY 次幂。
SQRT(X)SELECT SQRT(16); -- 4返回 X 的平方根。
RAND()SELECT RAND();返回一个 01 之间的随机浮点数。
SIGN(X)SELECT SIGN(-10); -- -1返回 X 的符号:-1 (负), 0 (零), 1 (正)。
日期和时间函数NOW() / SYSDATE()SELECT NOW();返回当前的日期和时间。NOW() 返回语句开始执行的时间,SYSDATE() 返回函数执行的实时时间。
CURDATE()SELECT CURDATE();返回当前日期(不包含时间)。
CURTIME()SELECT CURTIME();返回当前时间(不包含日期)。
DATE(expr)SELECT DATE('2025-10-21 10:30:45'); -- 2025-10-21提取日期时间表达式中的日期部分。
TIME(expr)SELECT TIME('2025-10-21 10:30:45'); -- 10:30:45提取日期时间表达式中的时间部分。
YEAR(date) / MONTH(date) / DAY(date)
HOUR(time) / MINUTE(time) / SECOND(time)
SELECT YEAR('2025-10-21'); -- 2025分别返回日期中的年、月、日,或时间中的时、分、秒。
DATEDIFF(date1, date2)SELECT DATEDIFF('2025-10-25', '2025-10-21'); -- 4返回 date1 减去 date2 的天数差。
TIMEDIFF(time1, time2)SELECT TIMEDIFF('10:30:00', '09:15:00'); -- 01:15:00返回 time1 减去 time2 的时间差。
DATE_ADD(date, INTERVAL expr unit)
DATE_SUB()
SELECT DATE_ADD('2025-10-21', INTERVAL 7 DAY); -- 2025-10-28在日期上增加/减去一个时间间隔。unit 可以是 SECOND, MINUTE, HOUR, DAY, MONTH, YEAR 等。
DATE_FORMAT(date, format)SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s');按指定格式字符串 format 格式化日期。常用格式符:%Y(4位年), %m(月), %d(日), %H(24小时), %i(分), %s(秒)。
STR_TO_DATE(str, format)SELECT STR_TO_DATE('2025/10/21', '%Y/%m/%d');将字符串按指定格式解析为日期时间。是 DATE_FORMAT 的逆操作。
条件函数IF(condition, value_if_true, value_if_false)SELECT IF(score >= 60, 'Pass', 'Fail') FROM grades;如果 condition 为真,返回 value_if_true,否则返回 value_if_false
IFNULL(expr1, expr2)SELECT IFNULL(price, 0) FROM products;如果 expr1 不是 NULL,返回 expr1,否则返回 expr2
NULLIF(expr1, expr2)SELECT NULLIF(column1, column2);如果 expr1 等于 expr2,返回 NULL,否则返回 expr1
CASE<br>SELECT <br> name,<br> CASE <br> WHEN score >= 90 THEN 'A'<br> WHEN score >= 80 THEN 'B'<br> ELSE 'C'<br> END AS grade<br>FROM students;实现多分支条件判断,类似于编程语言中的 switchif-else if
聚合函数COUNT(*)/COUNT(1)SELECT COUNT(*) FROM table;返回结果集的总行数(包含 NULL 值)。
COUNT(表达式)SELECT COUNT(column) FROM table;返回指定表达式NULL 值的行数。
COUNT(DISTINCT 表达式)SELECT COUNT(DISTINCT column) FROM table;返回指定表达式中不同(去重)且非 NULL 值的数量。
SUM(数值表达式)SELECT SUM(price * qty) FROM sales;计算数值表达式的总和。忽略 NULL
SUM(DISTINCT 数值表达式)SELECT SUM(DISTINCT price) FROM products;计算不同数值表达式的总和。
AVG(数值表达式)SELECT AVG(score) FROM students;计算数值表达式的平均值。忽略 NULL
AVG(DISTINCT 数值表达式)SELECT AVG(DISTINCT salary) FROM employees;计算不同数值表达式的平均值。
MAX(表达式)SELECT MAX(age) FROM users;返回表达式的最大值(数值、字符串、日期)。忽略 NULL
MIN(表达式)SELECT MIN(price) FROM products;返回表达式的最小值(数值、字符串、日期)。忽略 NULL
GROUP_CONCAT([DISTINCT] expr [,expr ...] [ORDER BY ...] [SEPARATOR str])SELECT GROUP_CONCAT(name ORDER BY name SEPARATOR ', ') FROM users GROUP BY dept;将分组内的值连接成一个字符串。可去重、排序、自定义分隔符。
STD(expr) / STDDEV() / STDDEV_POP()SELECT STD(salary) FROM employees;返回表达式的总体标准差
STDDEV_SAMP(expr)SELECT STDDEV_SAMP(salary) FROM employees;返回表达式的样本标准差
VAR_POP(expr)SELECT VAR_POP(salary) FROM employees;返回表达式的总体方差
VAR_SAMP(expr)SELECT VAR_SAMP(salary) FROM employees;返回表达式的样本方差
BIT_AND(数值表达式)SELECT BIT_AND(flags) FROM config;对分组内所有值的二进制表示执行按位与(AND)操作。
BIT_OR(数值表达式)SELECT BIT_OR(flags) FROM config;对分组内所有值的二进制表示执行按位或(OR)操作。
BIT_XOR(数值表达式)SELECT BIT_XOR(id) FROM temp_table;对分组内所有值的二进制表示执行按位异或(XOR)操作。
JSON_ARRAYAGG(表达式)SELECT JSON_ARRAYAGG(name) FROM users;将值聚合成一个 JSON 数组
JSON_OBJECTAGG(key, value)SELECT JSON_OBJECTAGG(id, name) FROM users;将键值对聚合成一个 JSON 对象
加密与哈希函数MD5(str)SELECT MD5('password');返回字符串的 MD5 128位校验和(十六进制字符串)。注意:MD5 已不安全,不应用于密码存储
SHA1(str) / SHA(str)SELECT SHA1('password');返回字符串的 SHA-1 160位校验和。同样不推荐用于密码
SHA2(str, hash_length)SELECT SHA2('password', 256);返回字符串的 SHA-2 系列哈希值。hash_length 可为 224, 256, 384, 512。比 MD5/SHA1 更安全。
AES_ENCRYPT(str, key)
AES_DECRYPT(crypt_str, key)
SELECT AES_DECRYPT(AES_ENCRYPT('data', 'key'), 'key');使用 AES 算法对数据进行加解密。需要密钥。
系统与信息函数VERSION()SELECT VERSION();返回 MySQL 服务器的版本号。
DATABASE() / SCHEMA()SELECT DATABASE();返回当前选定的数据库名。
USER() / CURRENT_USER()SELECT USER();返回当前 MySQL 用户的用户名和主机名。
LAST_INSERT_ID()SELECT LAST_INSERT_ID();返回最后一个 AUTO_INCREMENT 值(在当前会话中)。

三、数据查询

1. 简单查询

1.1 查询表中全部数据

通过 SELECT * 语法查询 course 表的所有字段和完整数据。

select * from course;

在这里插入图片描述

1.2 查询表中指定字段的数据

指定 course 表的 course_no、course_name、teacher_name 三个字段进行查询。

select course_no, course_name, teacher_name from course;

在这里插入图片描述

1.3 查询表中指定字段的数据并起别名

在查询 course 表指定字段的基础上,通过 AS 关键字(部分场景可省略)为字段设置中文别名,提升查询结果的可读性,展示字段别名的使用技巧。

select course_no as '课程号', course_name as '课程名', teacher_name '授课教师' from course;

在这里插入图片描述

1.4 查询表中指定字段不重复的数据

使用 DISTINCT 关键字对 course 表的 teacher_name 字段去重查询,仅返回该字段的唯一值,适用于获取无重复的字段信息场景。

select distinct teacher_name from course;

在这里插入图片描述

1.5 查询表中前10条数据

借助 LIMIT 子句限制 course 表的查询结果,仅返回前 10 条数据,展示快速获取表内部分数据的方法,常用于数据预览。

select * from course limit 10;

在这里插入图片描述

2. 条件查询

2.1 比较运算符查询

2.1.1 查询表中分数大于90的数据

使用 > 比较运算符,筛选 student_course 表中 score 字段值大于 90 的记录,展示通过比较运算筛选符合数值条件的数据。

select * from student_course where score > 90;

在这里插入图片描述

2.1.1 查询表中选课无效的数据

使用 = 比较运算符,筛选 student_course 表中 is_valid 字段值为 0(代表无效)的记录。

select * from student_course where is_valid = 0;

在这里插入图片描述

2.2 范围运算符查询

2.2.1 查询表中分数大于等于80且小于等于90的数据

使用 BETWEEN … AND … 范围运算符,筛选 student_course 表中 score 字段值在 80-90(含边界)范围内的记录,简化连续数值范围的筛选逻辑。

select * from student_course where score between 80 and 90;

在这里插入图片描述

2.2.2 查询表中分数不是大于等于80且小于等于90的数据

在 BETWEEN … AND … 基础上添加 NOT 关键字,筛选 student_course 表中 score 字段值不在 80-90 范围内的记录,展示反向范围筛选的实现方式。

select * from student_course where score not between 80 and 90;

在这里插入图片描述

2.3 空值判断运算符查询

2.3.1 查询表中分数为空的数据

使用 IS NULL 空值判断运算符,筛选 student_course 表中 score 字段值为 NULL(代表未考试)的记录,明确空值筛选的正确语法(区别于 = NULL)。

select * from student_course where score is null;

在这里插入图片描述

2.3.2 查询表中分数不为空的数据

使用 IS NOT NULL 空值判断运算符,筛选 student_course 表中 score 字段值非空的记录,展示排除空值数据的查询方法。

select * from student_course where score is not null;

在这里插入图片描述

2.4 逻辑运算符查询

2.4.1 查询表中分数大于等于80且小于等于90的数据

通过 AND 逻辑运算符连接两个比较条件,筛选 student_course 表中 score 字段值同时满足 “≥80” 和 “≤90” 的记录,实现多条件的 “且” 逻辑筛选。

select * from student_course where score >= 80 and score <= 90;

在这里插入图片描述

2.4.2 查询表中专业是数学或计科的数据

使用 OR 逻辑运算符连接两个等值条件,筛选 student 表中 major 字段为 “数学与应用数学” 或 “计算机科学与技术” 的记录,实现多条件的 “或” 逻辑筛选。

select * from student where major = '数学与应用数学' or major = '计算机科学与技术';

在这里插入图片描述

2.4.3 查询表中专业不是数学或计科的数据

在 OR 组合条件外添加 NOT 关键字,筛选 student 表中 major 字段既不是 “数学与应用数学” 也不是 “计算机科学与技术” 的记录,实现多条件的反向逻辑筛选。

select * from student where not (major = '数学与应用数学' or major = '计算机科学与技术');

在这里插入图片描述

2.5 集合运算符查询

2.5.1 查询表中专业是数学或计科的数据

使用 IN 集合运算符,将 “数学与应用数学”“计算机科学与技术” 作为值列表,筛选 student 表中 major 字段在该列表内的记录,简化多值 “或” 逻辑的筛选语法。

select * from student where major in ('数学与应用数学', '计算机科学与技术');

在这里插入图片描述

2.5.2 查询表中专业不是数学或计科的数据

在 IN 基础上添加 NOT 关键字,筛选 student 表中 major 字段不在指定值列表内的记录,实现多值的反向筛选。

select * from student where major not in ('数学与应用数学', '计算机科学与技术');

在这里插入图片描述

2.6 模式匹配运算符查询

2.6.1 查询表中姓吴的同学的数据

使用 LIKE 模式匹配运算符结合通配符 %(匹配任意字符),筛选 student 表中 student_name 字段以 “吴” 开头的记录,实现按姓氏模糊查询。

select * from student where student_name like '吴%';

在这里插入图片描述

2.6.2 查询表中姓名包含娟字的同学的数据

通过 LIKE 搭配 % 通配符(前后均加),筛选 student 表中 student_name 字段包含 “娟” 字的记录,适用于查询姓名中含特定字符的场景。

select * from student where student_name like '%娟%';

在这里插入图片描述

2.6.3 查询表中专业为两个字且第二个字为学的数据

使用 LIKE 结合通配符 _(匹配单个字符),筛选 student 表中 major 字段长度为 2 且第二个字是 “学” 的记录,展示精确字符位置的模糊查询方法。

select * from student where major like '_学';

在这里插入图片描述

3. 函数查询

3.1 聚合函数查询

3.1.1 查询表中的最高分和最低分

使用 MAX() 和 MIN() 聚合函数,分别计算 student_course 表 score 字段的最大值(最高分)和最小值(最低分),实现对数值字段极值的统计。

select max(score) '最高分', min(score) '最低分' from student_course;

在这里插入图片描述

3.1.2 查询指定学生的总分和平均分

针对 student_course 表中 student_id = 1103 的特定学生,使用 SUM() 计算其 score 字段总和(总分),AVG() 计算平均值(平均分),展示对单个对象的数值统计。

select sum(score) '总分', avg(score) '平均分' from student_course where student_id = 1103;

在这里插入图片描述

3.1.3 查询指定学生所选课程数

筛选 student_course 表中 student_id = 1105 的记录,通过 COUNT() 统计该学生的 course_id 字段数量,得到其选课总数,示例按条件统计记录数的方法。

select student_id, count(course_id) '课程数' from student_course where student_id = 1105;

在这里插入图片描述

3.1.4 查询指定表数据量

分别使用 COUNT(*) 和 COUNT(1) 两种语法,统计 student_course 表的总行数,展示两种常用的表数据量统计方式,两种方法结果一致且均包含所有记录。

select count(*) from student_course;

select count(1) from student_course;

在这里插入图片描述

4. 分组、排序和限制查询

4.1 查询每个专业的学生人数

使用 GROUP BY 按 student 表的 major 字段分组,结合 COUNT(*) 统计每个专业的学生数量,实现按指定字段分组并统计各组数据量的需求。

select major, count(*) '学生人数' from student group by major;

在这里插入图片描述

4.2 查询每个专业的学生人数并筛选

在按 major 分组统计学生人数的基础上,通过 HAVING 子句筛选出人数≥25 的专业,展示对分组结果进行二次条件过滤的方法(区别于 WHERE 对原始数据的筛选)。

select major, count(*) '学生人数' from student group by major having count(*) >= 25;

在这里插入图片描述

4.3 按学号升序查询

使用 ORDER BY 子句按 student 表的 student_no 字段升序(ASC,默认可省略)排列查询结果,实现数据按指定字段从小到大的排序。

select * from student order by student_no asc;

在这里插入图片描述

4.4 按学号降序查询

通过 ORDER BY 结合 DESC 关键字,按 student 表的 student_no 字段降序排列查询结果,实现数据按指定字段从大到小的排序。

select * from student order by student_no desc;

在这里插入图片描述

4.5 按学号升序查询并限制返回20条数据

在按 student_no 升序排序的基础上,通过 LIMIT 子句限制仅返回前 20 条数据,结合排序和数量限制,适用于分页展示等场景。

select * from student order by student_no asc limit 20;

在这里插入图片描述

http://www.dtcms.com/a/513363.html

相关文章:

  • Linux相关概念和易错知识点(47)(五种IO模型、多路转接、select、poll、epoll)
  • jq动画效果网站wordpress 两个数据库 互通
  • 网站如何做淘宝推广食品经营许可证
  • wordpress 架站 电子书三水区网站建设
  • opendds初入门之monitor监控的简单练习
  • 清新区住房和城乡建设局网站企业建设H5响应式网站的5大好处
  • 做营利网站的风险太原网站建设制作报价
  • 在Jetson 上使用Intel RealSense D435运行RTAB-Map就行建图
  • 怎么建立自己的网站域名咸阳软件开发公司
  • 织梦做的网站怎样做小程序的平台
  • 律师在哪个网站做推广好深圳哪个网站发布做网站
  • 三字型布局的网站中国肩章大全图解
  • 响应式网站成本品牌官网建设内容
  • 提供网站备案建设服务大连甘井子区社区工作者招聘
  • 公司网站开发费用大概多少商品交易平台
  • 徐州网页设计seo前景
  • 【Linux】基本指令(入门篇)(下)
  • 湛江企业网站黄山旅游攻略自由行攻略
  • 音酷网站建设那些网站后台做推广效果好
  • Polar 逆向(简单难度)
  • 青岛网站建设比较好做外贸都做哪些网站好免费
  • 做自己的网站有什么用农村自建房设计图120平方二层
  • FITC-PEG-Silane|荧光素-聚乙二醇-硅烷|化学特性与功能
  • MyBatis-Plus-使用
  • 企业网站的常见服务是什么施工企业成立技术中心的好处
  • 软件下载大全网站家里电脑可以做网站空间吗
  • [MySQL] 联合查询
  • 黑客马拉松竞赛中产品成功要素与商业价值实现[特殊字符]
  • 做物流网站的公司网络规划设计师报名
  • 网站项目建设的必要性德国红点设计奖官网