MYSQL笔记

发布于:2025-05-19 ⋅ 阅读:(20) ⋅ 点赞:(0)

整理一下之前的学习记录

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可能得选择如下:

.  任意
|  or
[]  范围
\-  范围
\\  转义、引用\\n
?  01次
{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()

可以同时使用多个函数image.png

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 条件会强制过滤所有不满足条件的行)。

同理可以联结多个表:

image.png

6 高级联结

表别名:

image.png

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

不同的联结

自联结:

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

使用子查询:

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

使用自联结:

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

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

外联结:
[LEFT/ RIGHT] OUTER JOIN
例如学生表记录学生,成绩表记录成绩,现在要查询学生的成绩

SELECT s.name, sc.subject, sc.grade FROM student s LEFT JOIN score sc ON s.id = sc.student_id;

使用左查询会让学生的记录全在,而就算没有对应的成绩也会显示未null
反之,右查询会让成绩的记录在,而没有对应学生的会显示null

联结中使用聚合函数

select a.1, count(b.2) as xx FROM1 as a LEFT OUTER JOIN2 as b ON a.xx=b.xx GROUP BY a.xx;

7 组合查询

UNION组合结果,

select * from b1 where xx='xx'
union
select * from2 where xx='xx' limit 10;

等效于使用 xx='xx' OR xx='xx'

UNION查询结果自动去除重复行,

UNION ALL不会。

注意组合查询后ORDER BY只能在结尾用一条,不能分别排序

8 全文本搜索

对比:1 比LIKE REGEXP效率高,他们要全表扫描,而这个使用了索引。

2 它会进行优先级判断,例如搜索的内容出现的多次的(出现很多次搜索的“你好”),会排序在最前面

要求:索引被搜索的列,创建使用 FULLTEXT 搜索用Match()Against()

创建表:

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会自动维护索引(自动更新)

使用:

SELECT not_text
FROM xxx
WHERE Match(xxx_text) Against('aabb');

在SELECT使用:

SELECT xxx_text, Match(xxx_text) Against('你好') AS rank 
FROM xxx;

返回所有的行,rank为计算出来的优先值

9 插入数据

INSERT 插入一行

INSERT INTO customers(1,2,
     li3,
	...)
VALUES('1',
      '2',
      ...)

可也不指定列名省略customers后的括号,但是要一一对应填写。

小知识:id int not null auto_increment 这样的列,会有默认值,可以填null后自动添加。

提交多条:

INSERT INTO customers(1,2,
     li3,
	...)
VALUES('1',
      '2',
       ...
),
      ('1',
      '2',
      ...
),

插入检索出的数据

INSERT SELECT

10 更新

UPDATE 表名 
SET 列名 = 'xxx'
WHERE xx='xx';

删除列的值,可以设置成NULL

11 删除

DELETE FROM 表名
WHERE xx=xx;

尽量不要使用不带WHERE子句的删除与修改,否则是操作每一行


网站公告

今日签到

点亮在社区的每一天
去签到