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

Mysql笔记

目录

sql的DML

增加语句

删除语句和truncate

更新语句

replace语句

select查询语句

简单的查询

等值判断

不等判断

逻辑运算符

查询时的别名使用

常见的条件查询

分组

分组后筛选

结果排序

分页功能​​​​​​​

分表

外键和多表关联

表与表之间的关联关系

多表关联查询

SQL中的函数

聚合函数

count(*) 和 count(1)和count(列名)区别

数值型函数


sql的DML

有关数据表的DML操作:INSERT INTO、DELETE、TRUNCATE、UPDATE、SELECT、条件查询、查询排序、聚合函数、分组查询

增加语句

就是给某张表进行数据插入

insert INTO table_name[(field1 [, field2 ……]) values(value1 [, vaule2 ……])  [,()]];

操作:

insert into t_user value(null,"晓晓",21,"女",null,null);

insert into t_user(name,age,gender) values("小柳",18,"男");

插入多条数据:
insert into t_user(name,age,gender) values("小王",18,"男"),("笑笑",20,"女");

删除语句和truncate

删除语言,请注意删除的条件!!!如果不带条件,则删除全表。

delete from table_name [where 条件];
truncate table table_name;

操作:

删除id=4的数据:
 delete from user where id=4;

删除全部数据:
 delete from user;

 truncate table user;

更新语句

更新就是修改表中的数据

update table_name set 字段1=新值 [, 字段2=新值, 字段3=字段3 + 1]   [where 条件];

操作:

 update t_user set age = 30 where id = 1;

 update t_user set age = 20, mark="xw" where id = 4;

 update t_user set age = age + 1 ;

replace语句

该语句是集更新和插入为一体的一个语句;如果表中没有这条数据,则执行插入,否则执行更新。

操作:

因为没有,所以插入数据
replace into t_user(id, name, mark) values(100, "test", "test");

有数据,所以更新
replace into t_user(id, name, mark) values(100, "test", "testest");

select查询语句

select *|字段1 [, 字段2 ……] from 表名称 [, 表名称2……] [where 条件] [group by 字段 [having 分组后的筛选]] [order by 字段 [desc|asc] [字段2 [desc|asc] ……]] [limit 分页]

简单的查询

select 字段列表    from 表名称     where 条件

操作:

查询所有数据:
select * from t_user;

查询需要的字段信息:
select id,name,age from t_user;

查询一个字段,一个等值条件:
select name from t_user where id = 1;

等值查询:
select age from t_user where name="lili";
select * from t_user where age=19;
alter table t_user add birthday datetime default now();
select * from t_user where birthday='2025-03-23 14:07:19';

select语句中的特殊情况:

对数值型数据列、变量、常量可以使用算数操作符创建表达式(+ - * /)
对日期型数据列、变量、常量可以使用部分算数操作符创建表达式(+ -)
运算符不仅可以在列和常量之间进行运算,也可以在多列之间进行运算。
    SELECT last_name, salary, salary*12
    FROM employees;
    
补充:+ 说明
-- MySQL的+默认只有一个功能:运算符
SELECT 100+80; # 结果为180
SELECT '123'+80; # 只要其中一个为数值,则试图将字符型转换成数值,转换成功做预算,结果为203
SELECT 'abc'+80; # 转换不成功,则字符型数值为0,结果为80
SELECT 'This'+'is'; # 转换不成功,结果为0
SELECT 'This'+'30is'; # ?猜测下这个结果是多少?
SELECT NULL+80; # 只要其中一个为NULL,则结果为NULL

等值判断

条件中,出现了相等值的判断,一般采用=进行判断。

  • = 判断两次的值是否相等

  • is 判断空null

  • is not null来判断不为空

  • <=> 可以判断null或者普通值

不等判断

!= 不等于

<>也是不等于

逻辑运算符

逻辑运算符是多条件关联的一种方式

and

or

not

注意:在sql中,如果要提升条件的运行顺序,或者提高条件的优先级别,则需要使用括号来提升。

查询时的别名使用

查询时,将结果的显示字段,使用一个其他名称来代替,就是别名。

查询总条数:
    select count(*) from t_user;

别名显示表格:
    mysql> select count(*) as count from t_user;

常见的条件查询
where:
    select name from t_user where age = 19;

WHERE中比较运算符:
    select name from t_user where age < 22;
其他比较运算符:
    select name,age from t_user where age between 21 and 22;
使用IN运算符:
    select name,age from t_user where age in (20,21,22);
使用LIKE运算符:
    select name,age from t_user where name like '_i%';

使用IS NULL运算符查询包含空值的记录
逻辑运算符:and、or、not

使用正则表达式:REGEXP
    <列名> regexp '正则表达式'
  	select * from product where product_name regexp '^2018';

分组

sql中,分组是一种统计概念。查询的数据,进行数据分析时,可能需要将相同的数据分成一组

group by 字段

select gender from t_user group by gender;

分组后筛选

如果直接在分组后的结果集上进行条件判断,将条件写在where中,会报错,因为:结果集是分组后才能做的判断,而where实在查询前的条件判断。所以不能使用where,必须使用having。但是having必须写在group by之后!没有分组,就不能写having,但是分组可以没有having。

select gender, count(gender) from t_user  group by gender having count(gender) > 5;

结果排序

将查询结果,以特定的顺序展示(升序或者降序)。

order by 字段 
order by 字段 asc|desc;
order by 字段 asc|desc, 字段2 ;

正序排:
    select * from t_user order by age;
    select * from t_user order by age asc;

倒序排:
    select * from t_user order by age desc;

在年龄按正序的基础上,id按倒序
    select * from t_user order by age , id desc;

分页功能

select语句,查询数据时,可能结果会非常多,此时就不能直接展示,分页展示。

总数量(all_data):查询 select count(*)

每页展示的数量(page_size):程序员定

当前页(cur_page):默认第一页,用户自己点击选择

总页数(all_page):总数量 % 每页的数量 == 0 整除后的商 : 商 + 1

limit num  # 查询多少条

limit num1, num2; # num1: 偏移量, num2 : 每页的数量  

limit cur_page * (page_size - 1), page_size;

分表

为什么分表:

数据直接都存储在一张表中:

  • 如果数据很大,性能会出现问题

  • 将不同的数据,如果放在同一个表中,可能数据冗余

  • 数据冗余,会导致数据可能出错

将不同的类型,采用不同的数据表进行存储,如果两张表或者多张表之间存在关联关系,则可以采用外键来描述这种关联关系。

主表中,一般是一个字段,改字段一般是从表的主键。

操作:

我们要先创建从表,否则数据插不进去

创建班级:
create table grade(
	id int auto_increment,
    name varchar(50) unique,
    primary key(id)
);

插入数据:
insert into grade(name) value("Java精品班"), ("python数据分析班"), ("网络安全班"), ("云原生高级班");


创建学生:
create table student(
    id int primary key auto_increment,
    name varchar(50) unique,
    gender enum("F", "M"),
    age int default 18,
    adddress varchar(255),
    class_id int
);

插入数据:
insert into student(name, class_id) values("张三", 1);
insert into student(name, class_id) values("李四", 2);
insert into student(name, class_id) values("王五", 1);
insert into student(name, class_id) values("林一", 3);
insert into student(name, class_id) values("萧二", 1);
insert into student(name, class_id) values("小五", 4);

当我们插入一条错误数据,那么我们查询时是无法查到的:

        insert into student(name, class_id) values("张三666", 44);

如果要避免出现这种情况,必须加入外键约束!

外键和多表关联

外键:指的是两张或者多张表之间关联关系的字段。

外键约束:是表的约束,是约束表在插入外键数据时能够正确的插入。

添加约束:

方法一:在创建表时添加
create table student(
    id int primary key auto_increment,
    name varchar(50) unique,
    gender enum("F", "M"),
    age int default 18,
    adddress varchar(255),
    class_id int,
    foreign key(class_id) references grade(id)
);

方法二:用alter
    ALTER TABLE 表名 ADD CONSTRAINT 外键名 FOREIGN KEY(外键字段名) REFERENCES 外表表名(主键字段名)
表与表之间的关联关系

当表与表之间存在了外键,这就意味着,这两张表之间存在某种关联关系。

一旦表存在了关联关系,则会进行外键设计,如何设计外键,设计在哪张表中?

  • 一对一 :外键可以设计在任意一张表中

  • 一对多 :外键必须设计在多方

  • 多对多 :创建第三张表,来专门描述两张表的关联关系

多表关联查询

当两张或者多张表之间存在了关联关系,往往多表查询,如果查询。

交叉连接

内连接

外链接

        左外连接

        右外连接

自连接

全连接

自然连接 【不建议使用,直到就行】数据库自动使用相同字段名称完成外键关联

select *|字段 [,……] from 表名称 [,表名称] ……

操作:

交叉连接(cross join):
    在查询多表时,不指定表的关联关系,数据只能全部匹配
    引发笛卡尔积现象
    select * from student, grade;
    
    sql98的标准写法:
    select * from student cross join grade;

内连接(常用):
    select * from student, grade where student.class_id  = grade.id;
    select * from student, grade where student.class_id=grade.id and student.name='张三';

    sql98的内连接方式时,如果不指定关联条件,不管怎么写,都是交叉连接:
    select * from student inner join grade;
    select * from student join grade;

    正确写法:
    select * from student inner join grade on (student.class_id=grade.id);
    select * from student join grade on (student.class_id=grade.id) where student.name = "张三";

    内连接,只能查询出,存在关联关系的数据,如果不存在关联关系,如目前没有班级的学生,目前没有学生的班级
    select * from student cross join grade on (student.class_id=grade.id) where student.name = "张三";

    如果要将这些没关联关系的数据查询出来,则需要使用外连接
    左引进,那么就是他的左边的表;右引进,那么就是他的右边的表
    select * from student left (outer) join grade on (student.class_id=grade.id);
    select * from student right (outer) join grade on (student.class_id=grade.id);

联合查询:(union 、union all)
    联合查询,必须保证查询的多条SQL返回的结果 结构必须一致,所以联合查询常见于查询一张表
    (select * from student where class_id = "1") union (select id, name from student where id > 3);  --会报错
    (select * from student where class_id = "1") union all (select * from student where id > 3);
    
自连接查询:
    表的外键指向自身
    创建一个模块表
    create table board (
	    id int primary key auto_increment,
	    name varchar(50) unique not null,
	    intro text,
	    parent_id int,
	    foreign key(parent_id) references board(id)
    );

一层一层嵌套:
    前端板块:html、css
    后端板块:java、python
    硬件板块:嵌入式
    python:python基础、django、python GUI开发
    css:css2、css3

    insert into board(name, parent_id) values("前端板块", null);
    insert into board(name, parent_id) values("后端板块", null);
    insert into board(name, parent_id) values("硬件板块", null);

    insert into board(name, parent_id) values("html", 1);
    insert into board(name, parent_id) values("css", 1);
    insert into board(name, parent_id) values("java", 2);
    insert into board(name, parent_id) values("python", 2);
    insert into board(name, parent_id) values("嵌入式", 3);

    insert into board(name, parent_id) values("python基础", 7);
    insert into board(name, parent_id) values("django", 7);
    insert into board(name, parent_id) values("python GUI开发", 7);
    insert into board(name, parent_id) values("css2", 5);
    insert into board(name, parent_id) values("css3", 5);


    查看一级板块名称:
    select name from board where parent_id is null;

    查看前端板块的二级名称:        (子查询)
    select name from board where parent_id = (select id from board where name = "前端板块");
    
    select * from board as b, (select id from board where name = "前端板块") as t where b.parent_id = t.id;


    查询二级名称
    select name from (select * from board where parent_id is not null) as t where t.parent_id in (1, 2, 3);


如果数据为空,则改为0;如果不为空,则不变
select ifnull(age,0) from student where id = 3;
select ifnull(age,0) from student where id = 2;

SQL中的函数

SQL中默认提供很多系统内置函数,帮助开发者实现各种需要的功能。

聚合函数

聚合函数对一组值进行运算,并返回单个值。也叫组合函数。
COUNT(*|列名) 统计行数
AVG(数值类型列名) 平均值
SUM (数值类型列名) 求和
MAX(列名) 最大值
MIN(列名) 最小值
除了COUNT()以外,聚合函数都会忽略NULL值。

count(*) 和 count(1)和count(列名)区别
  1. count(1) and count(*)

    当表的数据量大些时,对表作分析之后,使用count(1)还要比使用count()用时多了! 从执行计划来看,count(1)和count()的效果是一样的。 但是在表做过分析之后,count(1)会比count(*)的用时少些(1w以内数据量),不过差不了多少。

    如果count(1)是聚索引,id,那肯定是count(1)快。但是差的很小的。 因为count(),自动会优化指定到那一个字段。所以没必要去count(1),用count(),sql会帮你完成优化的 因此:count(1)和count(*)基本没有差别!

  2. count(1) and count(字段) 两者的主要区别是 (1) count(1) 会统计表中的所有的记录数,包含字段为null 的记录。 (2) count(字段) 会统计该字段在表中出现的次数,忽略字段为null 的情况。即不统计字段为null 的记录。

  3. count(*) 和 count(1)和count(列名)区别

    执行效果上: count(*)包括了所有的列,相当于行数,在统计结果的时候,不会忽略列值为NULL count(1)包括了忽略所有列,用1代表代码行,在统计结果的时候,不会忽略列值为NULL count(列名)只包括列名那一列,在统计结果的时候,会忽略列值为空(这里的空不是只空字符串或者0,而是表示null)的计数,即某个字段值为NULL时,不统计。

执行效率上:   

列名为主键,count(列名)会比count(1)快

列名不为主键,count(1)会比count(列名)快

如果表多个列并且没有主键,则 count(1) 的执行效率优于 count(*)

如果有主键,则 select count(主键)的执行效率是最优的

如果表只有一个字段,则 select count(*)最优。

数值型函数
函数名称作用
ABS求绝对值
SQRT求平方根
POW 和 POWER两个函数的功能相同,返回参数的幂次方
MOD求余数
CEIL 和 CEILING两个函数功能相同,都是返回不小于参数的最小整数,即向上取整
FLOOR向下取整,返回值转化为一个BIGINT
RAND生成一个0~1之间的随机数,传入整数参数是,用来产生重复序列
ROUND对所传参数进行四舍五入
SIGN返回参数的符号

相关文章:

  • el-table单元格编辑,动态增删行,回车/上下左右箭头切换单元格
  • cpp-友元
  • 马科维茨均值—方差理论推导过程
  • 分布式系统设计陷阱,白话CAP理论
  • CVE-2020-0796:永恒之黑实战学习
  • Redis + 布隆过滤器解决缓存穿透问题
  • 微服务 - 中级篇
  • WebLogic中间件常见漏洞
  • sqrt函数(豆包)
  • 【leetcode100】搜索二维矩阵
  • 整合vue+Element UI 开发管理系统
  • 浅谈布隆过滤器(Bloom Filter)
  • kotlin知识体系(四) : inline、noinline、crossinline 关键字对应编译后的代码是怎样的 ?
  • 西门子G120扭矩控制
  • 系统设计类问题回答模板
  • 平芯微PW5012应用电路
  • emWin自定义键盘布局
  • 实验一、Linux环境下实现进度条小程序:深入解析核心实现与关键技术细节
  • 英伟达有哪些支持AI绘画的 工程
  • VMWare虚拟机磁盘扩容
  • 北京公园使用指南
  • 安阳一村支书微信群骂村民被警方行拘,辩称对方先“污蔑造谣”
  • 周口一乡镇公务员“被老赖”,两年4场官司均败诉,市监局将线索移送公安厅
  • 在上海生活8年,13岁英国女孩把城市记忆写进歌里
  • 一季度规模以上工业企业利润由降转增,国家统计局解读
  • 湖南小伙“朱雀玄武敕令”提交申请改名为“朱咸宁”