MYSQL笔记

整理一下之前的学习记录

1 基础

DISTINCT 去重

ORDER BY (DESC)【最后对数据排序,所以要先筛选WHERE】

WHERE = != < >= BETWEEN IS NULL 【如果对WHERE后的值进行修改:a+1, 强制类型转换,会导致索引失效】

AND OR 条件判断

执行顺序:[1] OR [2] AND [3] 会先执行AND 再 OR 所以需要加()

IN (合法值1,合法值2) 本质等于 合法1 OR 合法2

NOT IN 不存在

通配符

LIKE

% 任意字符出现任意次数 例:找到 查询 开头的数据:SELECT... WHERE xxx LIKE '查询%' 类比正则 .*

_ 匹配任意字符 1次 例:找到 ID 为20x 的数据(200-209) SELECT ... WHERE ID LIKE '20_' 类比正则.

REGEXP (使用正则表达式)

WHERE column REGEXP 'pattern'

pattern可能得选择如下:

sql 复制代码
.  任意
|  or
[]  范围
\-  范围
\\  转义、引用\\n
?  0或1次
{n}  n次
^ $  定位符号

计算字段 (都用于select中,为不存在的字段1)

连接 concat(列1,'--',列2)期间可以插入字符

别名 AS

支持基础运算 ±*/

2 函数

如之前的concat (拼接) RTrim(去空格)

Upper()大写

Lower()小写

时间 Date()

要使用yyyy-mm-dd的形式

找某一天要用 select * from table1 where Date(order_day) == '2025-05-08'

找月份可以 。。。 where year(order_day) = 2025 and month(order_day) = 05

数字处理 abs() rang() mod()....

汇总数据

聚集函数(找长度、求和、最值)count() sum() max() min()

可以同时使用多个函数

3 分组数据

计算某一标签的用例数量

select count(*) from 表名 where 列 = 'xxx,';

count() count(列)------通常使用会有优化,会使用索引。但差异通常很小。.

group by 依据某一列分组查询行数(查看用例标签都有多少用例)

select xx, count(*) from 表 group by 列 limit 10;

在group by之后计算了count(*) 后,如果要筛选不能用WHERE 要用HAVING

注意

  • 1、使用group by要求select中的所有列都要体现在group by 后,
  • 2、如果只是想展示某一列而不像用来分组,要使用聚合函数包围该列如max()
  • 3、不建议关闭only_full_group_by模式

在分组之后希望进行筛选,要使用HVING

4 子查询

需要连续查询时

结果1 : 查询 xxx from xxx where xxx

结果2 : 查询 xxx from xxx where 结果1

结果2 : 查询 xxx from xxx where 结果2

可以使用() 嵌套查询,但实际会执行3次操作

查询 xxx from xxx where xxx in (查询 xxx from xxx where 【得到结果2】(查询 xxx from xxx where xxx 【得到结果1】))

作为计算的子查询

表1存放测试套件

表2存放测试用例

想要得到表1对应的表2有多少用例:

select 列1, 列2, (select count(*) from 表2 where 表2.列 = 表1.列) as xx_count from 表1;

注意这里需要 【完全限定类名】,否则如果列名重名会出现错误

5 联结

供应商、商品的关系,存在两个数据表中,如果重复在商品表中存储供应商的信息,会浪费空间与难以管理(每次输入供应商信息要一致)。

所以在 商品 表中存储 供应商 表的id(主键)其他信息不存储,这样就通过供应商表的id 关联了两个数据库表

这时候, 供应商id(主键)叫做 商品表中的外键 提升了 可伸缩性

在一条SELECT中查询:

FROM中写了两个表,要在WHERE中确定两个表的联结关系(这时候要写【完全限定类名】)

select 列1, 列2, 列3 from 表2, 表1 where 表2.xx= 表1.学习order by 学习limit 10;

如果没有在WHERE中确定联结关系,这会按"笛卡尔积"的方式进行显示(第1个表的行数 * 第二个表的行数)

不用WHERE的联结写法------内部联结 强烈推建

1 语法逻辑不同

INNER JOIN:显式声明了 "表之间的联结关系",通过 ON 子句明确指定联结条件,逻辑上更贴近 "先关联表,再过滤结果" 的过程。

WHERE 隐式联结:通过 FROM 子句并列多个表(逗号分隔),然后在 WHERE 中用条件模拟联结,逻辑上更像 "先笛卡尔积所有表,再过滤无效行"。

2 可读性与可维护性

INNER JOIN:结构清晰,联结条件(ON)和过滤条件(WHERE)分离,尤其在多表联结时(如 3 张以上表关联),能明确看到每张表的关联关系。

WHERE 隐式联结:所有条件混杂在 WHERE 中,需从大量条件中区分哪些是联结条件、哪些是过滤条件,复杂查询中可读性差。

3 对 "外联结" 的兼容性

INNER JOIN 是显式联结语法的一部分,可轻松扩展为 LEFT JOIN/RIGHT JOIN 等外联结(保留某表全部行)。

WHERE 隐式联结 无法直接表达外联结逻辑。例如,若试图用 WHERE 模拟 LEFT JOIN,可能意外过滤掉 "主表无匹配的行"(因为 WHERE 条件会强制过滤所有不满足条件的行)。

同理可以联结多个表:

6 高级联结

表别名:

在FROM后给表都起了别名:可以缩短sql长度

不同的联结

自联结:

想知道 同在一张表中的 某一生产物的供应商的其他生产物品:

使用子查询:

sql 复制代码
SELECT 产物id, 产物名 FROM 产品表 WHERE (SELECT 供应商id FROM 产品表 WHERE 产物id = '某一生产物');

使用自联结:

sql 复制代码
SELECT 产物id, 产品名 FROM 产品表 as p1, 产品表 as p2 WHERE p1.供应商id = p2.供应商id AND p2.产物id = '某一生产物';

产品表出现了两次,要使用表别名重新命名,再通过WHERE子句联结。

外联结:

LEFT/ RIGHT\] OUTER JOIN 例如学生表记录学生,成绩表记录成绩,现在要查询学生的成绩 ```sql SELECT s.name, sc.subject, sc.grade FROM student s LEFT JOIN score sc ON s.id = sc.student_id; ``` 使用左查询会让学生的记录全在,而就算没有对应的成绩也会显示未null 反之,右查询会让成绩的记录在,而没有对应学生的会显示null 联结中使用聚合函数 ```sql select a.列1, count(b.列2) as xx FROM 表1 as a LEFT OUTER JOIN 表2 as b ON a.xx=b.xx GROUP BY a.xx; ``` ## 7 组合查询 UNION组合结果, ```sql select * from b1 where xx='xx' union select * from 表2 where xx='xx' limit 10; ``` 等效于使用 `xx='xx' OR xx='xx'` UNION查询结果自动去除重复行, UNION ALL不会。 注意组合查询后ORDER BY只能在结尾用一条,不能分别排序 ## 8 全文本搜索 对比:1 比LIKE REGEXP效率高,他们要全表扫描,而这个使用了索引。 2 它会进行优先级判断,例如搜索的内容出现的多次的(出现很多次搜索的"你好"),会排序在最前面 要求:**索引**被搜索的列,创建使用 FULLTEXT 搜索用Match()Against() 创建表: ```sql CREATE TABLE xxx ( xxx_id int NOT NULL AUTO_INCREMENT, xxx_date datetime NOT NULL, xxx_text text NOT NULL, PRIMARY KEY(note_id), FULLTEXT(note_text) )ENGINE=MyISAM; ``` FULLTEXT后,mysql会自动维护索引(自动更新) 使用: ```sql SELECT not_text FROM xxx WHERE Match(xxx_text) Against('aabb'); ``` 在SELECT使用: ```sql SELECT xxx_text, Match(xxx_text) Against('你好') AS rank FROM xxx; ``` 返回所有的行,rank为计算出来的优先值 ## 9 插入数据 INSERT 插入一行 ```sql INSERT INTO customers(列1, 列2, li3, ...) VALUES('1', '2', ...) ``` 可也不指定列名省略customers后的括号,但是要一一对应填写。 小知识:id int not null auto_increment 这样的列,会有默认值,可以填null后自动添加。 提交多条: ```sql INSERT INTO customers(列1, 列2, li3, ...) VALUES('1', '2', ... ), ('1', '2', ... ), ``` 插入检索出的数据 INSERT SELECT ## 10 更新 ```sql UPDATE 表名 SET 列名 = 'xxx' WHERE xx='xx'; ``` 删除列的值,可以设置成NULL ## 11 删除 ```sql DELETE FROM 表名 WHERE xx=xx; ``` 尽量不要使用不带`WHERE`子句的删除与修改,否则是操作每一行

相关推荐
Sunshine~L&H1 小时前
Mac 上使用 mysql -u root -p 命令,出现“zsh: command not found: mysql“?如何解决
数据库·mysql·macos
chanalbert2 小时前
数据库连接池深度研究分析报告
数据库·spring
snpgroupcn3 小时前
泰国零售巨头 CJ Express 借助 SAP 内存数据库实现高效数据管理
数据库·express·零售
忘川w3 小时前
《网络安全与防护》知识点复习
笔记·安全·web安全·网络安全
FJSAY3 小时前
我自己动手写了一个MySQL自动化备份脚本,基于docker
mysql·docker·自动化
zkinglin4 小时前
AORSA编译指南
笔记·其他·能源
明月看潮生5 小时前
青少年编程与数学 01-011 系统软件简介 19 SSMS 数据库管理工具
数据库·青少年编程·编程与数学
一勺菠萝丶5 小时前
宝塔安装MySQL无法远程连接【已解决】
mysql
blammmp5 小时前
Redis : set集合
数据库·redis·缓存
翔云1234565 小时前
精准测量 MySQL 主从复制延迟—pt-heartbeat工具工作原理
数据库·mysql