day31 MySQL(一)


I know, i know
地球另一端有你陪我




一、基础

关系型数据库
关系模型就是一对一,一对多,多对多等关系模型,关系模型就是存储格式是以行列组成的二维表格,所以一个关系型数据库就是由二维表之间的联系所组成的一个数据组织

非关系型数据库
由于关系型太大和复杂,所以一般使用“非关系型数据”来表示其他类型的数据库
菲关系型的模型比如:
列模型
存储的数据是一列一列,关系型数据库以一行作为一个记录,列模型数据库以一列为一个记录
键值对模型:
存储的数据是一个个键值对,比如name:lisi
文档类模型:
以一个个文档来存储数据,类似于键值对

二、SQL

Structured Query Language
结构化查询语言

执行语句不区分大小写

分类

1、DDL
数据定义语言 - Data Definition Language
用来定义数据库的对象,如数据表、视图、索引等

2、DML
数据处理语言 - Data Manipulation Language
在数据库表中更新,增加和删除记录
如 update, insert, delete

3、DCL
数据控制语言 – Data Control Language
指用于设置用户权限和控制事务语句
如grant,revoke,if…else,while,begin transaction

4、DQL
数据查询语言 – Data Query Language
select

1、数据库相关

1、显示数据库

	show databases

2、创建数据库 fgh

	create database [if not exists] fgh

3、显示数据库创建

	show create database fgh

4、删除数据库 fgh

	drop database if exists fgh

5、切换至数据库 fgh

	use fgh

6、查看当前数据库

	select database()

7、修改数据库 fgh 的编码为 utf-8

	alter database fgh character set utf8

数据库无法改名

2、表

服务器->数据库->表(行列组成的二维表格)->行
client操作服务器通过命令登录操作:mysql -u用户名(默认root) -p密码

1、创建表

	create table if not exists fgh(
		id int(11) not null auto_increment,
		//	字段 数据类型 字段属性
		name varchar(255) not null,
		age int(11),
		sex enum('1','0') not null;,
		primary key(id)
	)engine innodb;
	字段属性:
	not null:没给值数据为默认值(varchar默认值为空)
	AUTO_INCREMENT:定义列为自增的属性,一般用于主键,数值会自动加1
	PRIMARY KEY:关键字用于定义列为主键,您可以使用多列来定义主键,列间以逗号分隔
	
	ENGINE 设置存储引擎,CHARSET 设置编码
	default null:没给值数据就是null
	default 值:设置字段的默认值

2、查看建表

	show create table fgh

3、查看表结构

	desc fgh

4、删除表

	drop table if exists fgh

5、修改表名为 fghaaa

	rename table fgh to fghaaa

6、表 fgh 后追加新字段 test

	alter table fgh add test varchar(255)

7、改变字段 test 的属性

	alter table fgh modify test int(11) not null

8、改变字段 test 的名字和属性

	alter table fgh change test test01 varchar(255)

9、 删除字段 test01

	alter table fgh drop test01

3、数据

1、插入数据

	insert into 
	fgh(name,age)
	values("fgh1",21)

2、查找数据

	查询 SELECT column_name,column_name
	FROM table_name
	select:显示数据到控制台
	from:获取数据
	select查询结果是一张表(特殊的表:用后即消失)
	select *,from fgh,where balabala
	-- >   <   <=   >=   =    <>	大于、小于、大于(小于)等于、不等于
	-- select * from students where age<>18;

	-- between  ...and...	显示在某一区间的值
	-- select * from students where age BETWEEN 19 and 23;

	-- in(set)	显示在in列表中的值,例:in(100,200)
	-- select * from students where age in(19,23);

	-- like '张_'	模糊查询  使用 % 多个和  _ 单个
	-- select * from students where name like 's%';
	-- select * from students where name like 's_';

	-- Is null	判断是否为空
	-- select * from students where address is null;

	-- and	多个条件同时成立
	-- or	多个条件任一成立
	-- not	不成立,例:where not(expection>10000);
	-- select * from students where sex="1" or age>=20;
	-- select * from students where not(age>20);

3、删除数据

	delete from fgh where age=18

4、修改数据

	update fgh set address='中国' where age<=20;

4、聚合函数

1、Count (列名)
     返回某一列,行的总数 (某一列有null不参与计算)

	select count(name) from student

2、sum (列名)
     求和中值为字符串的会当做0处理(数值的字符串当做数字处理)

	select sum(age) from student

     同理,max(最大值) min(最小值) avg(平均值)

3、子查询(嵌套 select)
     查询所有分数大于均值的

	select * from student where test>(select avg(test) from student)

4、distinct (去重)
     去重显示同年龄的数据

	select distinct age from student

     注:distinct 多个字段时,会同时参与判定

5、concat concat_ws(数据显示连接)

	select *,concat(name,",",age,",",sex)  from student
	select *,concat_ws(",",name,age,sex) from student

     注:连接的数据会显示在一个新增的列

5、时间

1、显示完整时间,二者功能相同

	select current_timestamp()
	select current_timestamp

2、显示日期

	select CURRENT_DATE()
	CURRENT_DATE

3、显示时刻

	select CURRENT_TIME()
	CURRENT_TIME

4、时间转 str

	select date_format("2021-11-04","%Y-%m-%d")
	select DATE_FORMAT(CURRENT_DATE(),"%Y=%m=%d")

5、str 转时间

	select str_to_date("2021-11-04","%Y-%m-%d")

6、时间做差
      前者减去后者,输出单位为 day

	select datediff("2021-11-04","2021-11-01")
	输出结果:3

7、时间前后顺延

	DATE_ADD(date,INTERVAL expr type)
	时间加上指定时间间隔
    DATE_SUB(date,INTERVAL expr type)
	时间加上指定时间间隔
	
	INTERVAL 关键字 一般不动
	expr 间隔的数值
	type 间隔的类型 year / month / day
	select date_add("2021-12-04",interval -4 day)
	输出:2021-11-30

8、例题
现有11月的一列日期,从11月1日到11月30日,将其按照七天一组,对日期进行分组

	思路:
		1、现将所有日期减去第一天的日期
		2、天数的差值除以7,向下取整 floor
		3、按照所得结果进行分类
date value
2021-11-01 1
2021-11-02 1
2021-11-03 1
2021-11-04 1
2021-11-05 1
2021-11-06 1
2021-11-07 1
2021-11-08 1
2021-11-09 1
select concat(
date_add("2021-11-01",interval floor(DATEDIFF(date,"2021-11-01")/7)*7 day),
"~",
date_add("2021-11-01",interval floor(DATEDIFF(date,"2021-11-01")/7)*7+6 day)
)as dategroup,sum(value)
from date group by dategroup

求连续登录天数大于3天的用户(暴力方法)

id date
1001 2021-11-01
1001 2021-11-02
1001 2021-11-03
1001 2021-11-04
1001 2021-11-06
1002 2021-11-01
1002 2021-11-02
1002 2021-11-04
1002 2021-11-05
1003 2021-11-01
1003 2021-11-02
1003 2021-11-03

思路:直接连表,大于三天,即连四次表,筛选出间隔一直为1的数据

select
u1.id ,u1.Date as date1,u2.Date as date2 ,u3.Date as date3 ,u4.Date as date4
from user as u1
inner join user as u2
on u1.id=u2.id and DATEDIFF(u2.Date,u1.Date)=1
inner join user as u3
on u2.id=u3.id and DATEDIFF(u3.Date,u2.Date)=1
inner join user as u4
on u3.id=u4.id and DATEDIFF(u4.Date,u3.Date)=1

6、数字处理

1、round 四舍五入

	select round(20.4555);
	select round(20.4555,1);
	select round(20.4555,2);
	输出结果:	20		
				20.5		
				20.46

2、floor 向下取整 ceil 向上取整

	select floor(10.9)
	select ceil(10.1)
	输出结果:	10		
				11

3、rand() 随机数 (0,1)

	select rand()*10
	输出结果:	7.31998791668563

7、排序、分组

1、order by 升序 asc、降序 desc

	select * from student order by age
	select * from student order by age desc

2、group by 分组

	select age,count(*) from student group by age
	输出结果:	    age count(*)
					16	   1
					18	   1
					19	   2
					20	   1
					21	   2
					22	   1
	按照年龄分组后,count(*) 计数一个组中的个数				
	注:多个字段的话,会按照排列组合进行分组

2、分组Top1 按sex分组后,求分组中年龄最大的一个

	方法一:
	1、先找出sex分组后,最大的两个值,再从原表中找出对应的完整数据
	select * from student where age in 
	(select max(age) from student group by sex);
	方法二:
	1、先从表一中,获取第一个数据的age,作为当前数据
    2、从表二中,查找与当前数据 sex 相同的数据,得到其中age最大的值max(age)
	3、返回表一中,匹配当前数据的age是否等于max(age)
	   如果是,就保留数据,等待输出;如果不是,就选择下一个数据作为当前数据

	简单理解为:从表二中找出最大的两个值,之后反过来匹配输出表一中对应的数据
	select * from student as stu1 where 
	age=(select max(age) from student as stu2 where stu1.sex=stu2.sex);

3、分组TopN 按sex分组后,求分组中年龄最大的三个

	1、先从表一中,获取第一个数据的age,作为当前数据
	2、从表二中,查找与当前数据 sex 相同的数据,比较获得age比当前数据小的个数
		个数越少,说明当前数据的age越大,返回当前数据比较结果的个数
	3、返回表一中,如果当前数据的个数足够小,就匹配,等待输出
				
	关于stu1.age<stu2.age,这样比较,需要的结果会在上层,方便获取
	关于是3>,数学逻辑,最大的三个数中最小的,只会小于上面两个数
select * from student as stu1  where 3>
	(select count(*) from student as stu2
		where stu1.sex=stu2.sex and stu1.age<stu2.age
		)order by sex ,age desc;

8、where & having

where:在 select 前进行搜索,搜索的原表
having:在 select 后进行搜索,搜索的是结果输出表

	select sex,count(*) from student group by sex where sex=1
	select sex,count(*) from student group by sex having sex=1
	结果:		第一句报错
				第二句正常运行

9、limit

用于选择输出的结果,默认从0开始

	limit 0,length

Guess you like

Origin blog.csdn.net/qq_41464008/article/details/121151001