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`子句的删除与修改,否则是操作每一行

相关推荐
kokotao15 分钟前
使用Java实现Navicat密码的加密与解密
java·开发语言·数据库·mysql
默心24 分钟前
centos7安装mysql8.0
运维·mysql·adb·centos·devops
傻傻虎虎38 分钟前
【QT】ModbusTCP读写寄存器类封装
开发语言·数据库·qt
NovakG_43 分钟前
Mysql面经
mysql·面经
STONE_KKK1 小时前
Django快速入门篇
数据库·django·sqlite
看到千里之外的云1 小时前
Oracle 11g post PSU Oct18 设置ssl连接(使用wallets)
数据库·oracle·ssl
绝迹的星2 小时前
MySQL与Redis一致性问题分析
数据库·redis·mysql
有时间要学习2 小时前
MySQL——基本查询&&内置函数
mysql
Johny_Zhao2 小时前
线下IDC数据中心迁移至阿里云详细方案
linux·网络·mysql·网络安全·信息安全·云计算·shell·数据迁移·yum源·系统运维·itsm
hkfkn2 小时前
Sql刷题日志(day9)
数据库·sql