一、查询1、执行顺序先找表、连接、过滤FROM/JOIN/WHERE再分组、聚合GROUP BY/HAVING最后开窗口计算排名 / 聚合OVER()再排序、分页SELECT 列1, 列2, 聚合函数(列) FROM 表名 [JOIN 其他表 ON 关联条件] WHERE 行过滤条件 GROUP BY 分组列 HAVING 分组过滤条件 ORDER BY 排序列 ASC/DESC LIMIT 偏移量, 数量;语法(inner) join连接只保留两张表中匹配成功 的行双方都有数据才保留)两表通过外键逐一拼接,不会保留存在a表中,但b表中无匹配成功外键的值left join 则只保留左表,不符合条件的行也会显示,显示nulldistinct 去重留下唯一IN不关心行数只关心值是否存在like 模糊查询,%匹配任意字符长度,_匹配单个常用函数1、字符串类CONCAT(列1, 列2) -- 字符串拼接LENGTH(列) -- 长度SUBSTRING(列, start, length) -- 截取UPPER(列) / LOWER(列) -- 大小写转换TRIM(列) -- 去空格2、数值类ROUND(数值, 位数) -- 四舍五入CEIL(数值) -- 向上取整FLOOR(数值) -- 向下取整ABS(数值) -- 绝对值3、条件类IF(条件, 真值, 假值)CASEWHEN 条件1 THEN 结果1WHEN 条件2 THEN 结果2ELSE 默认值END2、exists的使用查询要求中包含有没有的判断使用exists结合select 1 进行判断如果要展示的查询结果中只有外表只需要在select 1 判断的时候将外表和内表进行结合而要展示内外表时在exists的外边使用join连接。#9 查询和 01 号的同学学习的课程完全相同的其他同学的信息 #关联内外两层表 sco.student_id s.id #exists(有结果) 返回ture || not exists(有结果) 返回false #select 1 表示判断 select s.* from students s where id ! 01 # 排除自身id #先查询课程总数一致的同学 and exists(select 1 from scores sco where sco.student_id s.id group by sco.student_id having count(distinct sco.course_id) (select count(distinct course_id) from scores where student_id 01)) #课程总数一致后查询每一门的课程是否一致 and not exists(select 1 from scores sco where sco.student_id s.id and sco.course_id not in (select course_id from scores where student_id 01));EXISTS 是 “行相关子查询”它判断的是「当前这一行对应的学生」是否满足条件而不是判断当前这一行本身。s.id 是外层学生表的学生 ID也就是说数据库对每一行都执行一次 EXISTS 判断判断 行 1学生 101 课去查学生 1有没有 01 课 60→ 有 →这一行保留判断 行 2学生 103 课去查学生 1有没有 01 课 60→ 依然有 →这一行也保留WHERE 普通条件过滤当前行WHERE EXISTS (关联外层学生 ID)过滤整个学生只要学生满足他的所有行都保留select distinct s.id,s.name,s2.course_id, s2.score from students s join scores s2 on s.id s2.student_id where exists( select 1 from scores sco where sco.student_id s.id and course_id 01 and score 60) ;3、窗口函数窗口函数 对一组行窗口进行计算但不会把多行合并成一行执行顺序窗口函数是在 WHERE、GROUP BY、HAVING 之后才执行的所以如果要查询窗口函数生成的表需要将其作为子查询嵌套查询。语法窗口函数() OVER ( PARTITION BY 分组列 ORDER BY 排序列 )OVER标志这是窗口函数PARTITION BY按什么分组可选ORDER BY组内按什么排序可选注意排名要全局就不要写 PARTITION BYPARTITION BY 是分组内排名不是全局排名比如说公司工资排名如果是部门单独排则需要使用但是公司所有人进行排序那么就不需要使用如果使用每个人都会成为单独的一组函数RANK () —— 跳跃排名eg1 1 3 4DENSE_RANK () ——连续排名 eg 1 2 2 3 4ROW_NUMBER () —— 行号永不重复eg1 2 3 4LAG(列值, 1, 0)——返回前n行的列的值可以用来对比比如说第二名和第一名的分差使用原分-返回的LEAD(col, n, default)——返回后n行列的值FIRST_VALUE(col)——取窗口内第一行对应的列值进阶函数NTILE(n)将数据平均分成 n 组标记组号 1~n#按各科成绩进行排序并显示排名 Score 重复时保留名次空缺 SELECT student_id, course_id, score, ROW_NUMBER() OVER ( PARTITION BY course_id ORDER BY score DESC ) AS single_rank FROM scores;结果4、日期类时间类型DATE → 2025-01-01DATETIME → 2025-01-01 12:30:45TIMESTAMP → 2025-01-01 12:30:45带时区select curdate(); #输出当前日期 select curtime();#输出当前时间 select now();#日期时间 select * from students where birth CURDATE();时间查询日期格式DATE_FORMAT(date, %Y-%m-%d) -- 转成 2026-03-29DATE_FORMAT(date, %Y年%m月%d日)DATE_SUB(日期, INTERVAL n 单位) 日期减法意思是日期减去n后得到的日期DATE_ADD日期, INTERVAL n 单位日期加法DATE_SUB(CURDATE(), INTERVAL 1 DAY) 当前日期减去1天也就是昨天的日期周yearweek月month年year嵌套使用查询# 查询下周过生日的学生 select * from students as st where week(st.birth) week(date_add(now(), interval 7 day));二、增删改数据DML增加insert into 表名字段values值删delete from 表名 where 条件drop userDELETE 删数据DROP 删表DELETE 可回滚DROP 不可回滚改update 表 set 字段值 where 条件