这周学习了MySQL数据库相关的知识,具体内容如下。
select 查询列表 from 表名;
1、查询列表可以是表中的字段,可以是常量,表达式和函数
2、查询的结果也是一个关系(表),是虚拟的
别名可以通过as和空格来定义
select ID as 编号,Name as 城市名 from city;
select ID 编号,Name 城市名 from city;
使用distinct去重复
select CountryCode from city;
select distinct CountryCode from city;
使用where子句进行查询出来结果的筛选
select
查询列表
from
表名
where
筛选条件;
在SQL语句的执行过程中,先根据查询列表得到所要查询的元组
然后在表名指定的某张表中得到该元组对应的关系
最后根据筛选条件将满足条件的数据查询出来
like:字符串模糊匹配
between and:限定值的范围
in:按集合筛选数据
is null:某字段设置为空的数据
安全等于 <=>
安全等于符号不仅可以判断NULL值,也可以进行值的判断
使用group by子句将表中的数据进行分组
use world;
select * from city;
分组前筛选,使用where对每一行进行筛选
select max(population), count(*), countrycode from city group by countrycode;
分组后筛选,使用having子句对分组后的行进行筛选
select countrycode, sum(population) from city group by countrycode having sum(population) > 20000000;
按多个字段分组查询
select countrycode, district, sum(population) from city group by countrycode, district;
按多个字段分组查询,并排序
select countrycode, district, sum(population) from city group by countrycode, district order by sum(population) desc;
select
查询列表
from
表名
[where
筛选条件]
order by
排序字段[asc|desc];
asc代表升序,desc代表降序,默认为升序。
order by支持按多字段排序,用逗号隔开,查询时会先前面的字段排序,再按后面字段进行二级排序。
select *
from city
where Population > 1000000
order by Population desc;
用于分批次展示数据
语法:
select 查询列表
from 表名
limit offset, size
offset是数据的起始索引,从0开始,若为零,可省略
size是要显示的数据条数
limit子句放在最后
select *
from city
where countrycode = “chn”
order by population desc
limit 0, 100;
union 联合 合并:将多个查询语句的结果合并成一个结果展示
语法:
select…
union
select…
union
.
.
.
.
.
(多条查询语句中间不写分号,并使用union连接)
注意:
使用union连接的多个select查询语句中,所查询的字段名必须数量相同,可以内容不相同,但是在输出时会混乱。
使用union all可以包含重复项(两条语句查询出来的重复项)
select id, name from city where population > 8000000
union
select id, name from city where population < 1000;
连接查询
这样的现象是笛卡儿积的错误,它将表的字段的笛卡儿积作为元组去查询
select * from student, teacher;
加上条件,这样就是等值连接,相应的,非相等的表达式就是非等值连接
select * from student, teacher where student.course = teacher.course;
自身连接是对一个表起两个别名,然后看作两个不同的表去查询
select s1.s_id,s2.s_name from student s1,student s2 where s1.s_id = s2.s_id;
select 查询列表
from 表1
[连接类型] join 表2
on 连接条件
select *
from student
inner join teacher
on student.course = teacher.course;
左外连接 与内链接的区别是内链接只会展示满足on之后连接条件的行
而左外连接会将left join左侧的表的全部数据都展示,满足连接条件的会展示连接部分的数据,不满足的会打印null
select *
from student
left outer join teacher
on student.course = teacher.course;
右外连接同理
select *
from student
right outer join teacher
on student.course = teacher.course;
全外连接会打印出两个表上的所有信息
妈耶 MySQL不支持全外连接。。。。这就很尴尬了
select student.,teacher.
from student
full join teacher
on student.course = teacher.course;
select 9140.48 + 828.06 + 3*36.72;
交叉连接,相当于用逗号连接
select S_name,T_name from student cross join teacher;
概念:将一组逻辑语句封装在方法中,对外只暴漏方法名。
分类:
函数之间可以进行嵌套使用。
字符函数
数学函数
日期函数
其他函数
流程控制函数
use world;
select * from city;
length():返回字符串的字节数。
select length(“哈哈哈”);
concat():拼接字符串函数。
select concat(id," - ",name),population from city;
upper(),lower():大小写转换函数,将查询得到的字符串进行大小写转换。
select upper(“hahahahahahahahaha”);
select lower(“HAHAHAHAHAHAHAHAHA”);
substr(srting, leftSub, sum):字符串截取函数从下表为leftSub开始截取字符串string的sum个字符
SQL中下标从1开始
select substr(“一二三四五六七八九十”, 5);
select substr(“一二三四五六七八九十”, 3, 2);
instr(sring, str):字符串str是字符串string的字串,该函数返回子串在主串中的起始位置,如果未找到字串,返回0。
select instr(“一二三四五六七八九十”, “六七八”);
trim([str from ]string):去掉字符串string前后的str子串,省略参数时默认为去掉空格
select trim(“a” from “aaaaaaaaaa哈aa哈aaaaaaaaaaaa”);
lpad(string, num, str):截取或者填充字符串,将串string填充或截取到长度为num,填充时使用串str填充
rpad(string, num, str):与lpad相似,不同点为lpad为左侧填充,rpad为右侧
select lpad(“abcdefg”, 20, “x”);
replace(string, str1, str2):使用str2替换string中的所有str1。
select replace(“aabbaabaabbaaabababbababa”,“ab”, “cc”);
round(double d, int i) 四舍五入,将d四舍五入i位
select round(1.678333, 3);
floot(double d):向下取整
select floor(9.999);
truncate(doublt d, int i):截断,将d的第i位之后的位截断。
select truncate(2.3456789, 3);
mod(n, i):取余n%i
select mod(10,3);
now():返回系统当前日期+时间
select now();
curdate():返回当前日期
select curdate();
curtime():返回当前时间
select curtime();
获取指定的部分时间,年、月、日、小时、分钟、秒。
select year(now());
select month(now());
select year(“2019-3-5”) 年;
select monthname(now());
str_to_date(str1, str2):字符串转时间类型
str1为要转换为时间的字符串
str2为字符串的格式
%Y 四位年份(2019)
%y 两位的年份(19)
%m 月份(04)
%c 月份(4)
%d 日(09)
%H 24小时制小时(13)
%h 12小时制小时(1)
%i 分钟(05)
%s 秒(06)
select str_to_date(“2019-4-9 13:39”, “%Y-%m-%d %H:%i”);
date_format(str1, str2):将日期按格式转换成字符串
select date_format(now(), “%Y 年 %m 月 %d 日”);
version():当前版本号
database():当前使用的数据库
user():当前的用户
select version(), database(), user();
if(a, b, c):相当于三目运算符
select name, if(population > 5000000, “big city!”, “just so so”) from city;
case语句三种用法
1、相当于switch
case 需要判断的表达式
when 常量1 then 要显示的语句,
······
else 要显示的语句
end
2、相当于if-else
case
when 条件1 then 要显示的语句,
······
else 不符合所有条件时要显示的语句
end
sum()求和, avg()求平均值, max()求最大值, min()求最小值, count()累计;
sum(), avg()一般用于数值型数据的处理
max(), min(), count可以处理任何类型
avg()在计算平均值时会忽略NULL值,同时不进行计数和distinct(去重)搭配
select sum(population), avg(population), max(population), min(population), count(population) from city;
统计列
select count(*) from city;
select count(1) from city;
和分组函数以同查询的字段是偶限制的
select name, avg(population) from city
作为子语句出现的select,被称为子查询
子查询出现的位置:
select之后
标量子查询
from之后
表子查询
where或having之后
标量子查询
列子查询
行子查询
exists之后
表子查询
结果集的行列数:
标量子查询,结果集只有一行一列
列子查询查询,结果一列多行
行子查询,结果一行多列
表子查询,结果多为多行多列
where后的子查询:标量子查询,列子查询,行子查询
特点: 子查询一般放在小括号内、条件右侧
标量子查询一般搭配单行操作符使用(>,<,=…)
查询编号为3的老师所带课的学生信息
select *
from student
inner join teacher
on student.course = teacher.course
where t_name = ( select t_name
from teacher
where t_id = 3
);
查询编号为4,5的老师所带课的学生信息
select *
from student
inner join teacher
on student.course = teacher.course
where t_name in ( select t_name
from teacher
where t_id in (4,5)
);
查询老师信息和所带的学生数
select distinct t.*,(
select count(*)
from student s
where s.Course = t.course) studentNum
from teacher t;
可以理解为在select返回的虚拟表中进行查询,或者使用其进行连接
select s.*, t.t_name
from student as s
inner join (
select t.T_Name,t.Course
from teacher as t
) as t
on s.course = t.course;
结果为0或1
语法:exists(查询语句),如果括号内的查询语句有结果,exists返回1,否则返回0
使用较少
select * from student;
select * from teacher;
select distinct t.*
from teacher as t
where exists(
select s.*
from student s
where s.course = t.course
);
insert into 表名 (列名。。。。)values (值。。。。)
列名和值应一一对应,省略列名表示所有列名
支持多条插入,支持子查询
insert into 表名 set 列名 = 值,列名 = 值,列名 = 值,列名 = 值,,。。。。。
修改单表:
update 表名
set 列名 = 新值,列名 = 新值,列名 = 新值,。。。
where 筛选条件
修改多表:使用了连接
update 表名1 连接类型 join 表名2
on 连接条件
set 列名 = 新值,列名 = 新值,列名 = 新值,。。。
方式一:delete
单表删除:
delete from 表名 where 筛选条件
多表删除:
delete 表1,表2
from 表1 [连接类型] join 表2 on 连接条件
where 筛选条件
方式二:trancate(删除整张表)
trancate table 表名;
delete和trancate区别:
trancate不可加where子句
trancate效率略高(不需要筛选)
delete删除整张表不会重置自增长列的值
trancate删除不能回滚,而delete删除可以
数据定义语言alter库和表的管理
创建
create database 数据库名;
create database [if not existe]数据库名;(不可重复执行) [若不存在,创建]
修改
alter database 库名 character set 字符集名;
删除
drop databases [if exists]数据库名; 如果存在,删除库
创建
create table 表名(
列名 列类型[长度] [约束条件],
列名 列类型[长度] [约束条件],
列名 列类型[长度] [约束条件],
列名 列类型[长度] [约束条件],
。
。
);
tinyint(1字节)、smallint(2字节)、mediumint(3字节)、int\integer(4字节)、bigint(8字节)
默认为有符号(无符号:unsigned)
若插入数值超出范围则会报异常并插入临界值
如果不设置长度,则使用默认长度(根据范围得出)
如果不设置零填充(zerofull),不会补零
浮点型:
float(m,d)4字节、double(m,d)8字节
定点型:(更精确)
dec/decimal(m,d)默认为(10,0)
串:char(m)固定长度字符、varchar(m)可变长度字符,这里的固定长度是指长度不足时是否进行补充
char可省略长度,默认为1,varchar不可省略长度
长文本:····
二进制:····
枚举类型:
enum(a,b,c),只能在枚举的元素中选择一个
集合类型:
set(a,b,c),与枚举不同的是,集合中可以选择多个成员
枚举和集合都只可以保存0~64个成员
时间类型:
\ 字节数 最小值 最大值
date 4字节 1000-01-01 9999-12-31
datetime 8字节 1000-01-01 00:00:00 9999-12-31 23:59:59
timestamp 4字节 19700101080001 2038年某个时刻
time 3字节 -838:59:59 838:59:59
year 1字节 1901 2155
not null: 非空约束,该字段不空为空,必须进行填充
default:默认约束,保证该字段有默认值
primary key:主键,保证该字段的数据有唯一性,且不能为空
unique:唯一,与主键不同的是可以为空
check:检查约束(MySQL不支持)
foreign key:外键,用于约束该字段的值必须来自外键连接的表中的主键
外键不是列级约束,非空、默认不是表级约束
列级约束写在列的后面,表级约束使用constraint起名,可以不起,有默认的约束名,不过添加多 条约束时,约束名不可重复
标识列:自增长列,可以不用手动插入值,系统提供默认的序列值 auto_increment
修改列名[和类型]; alter table 表名 change column 旧列名,新列名[,新列类型];
修改列类型或约束: alter table 表名 modify column 列名,新列类型;
添加新列: alter table 表名 add column 列名,列类型;
删除列: alter table 表名 drop column 列名;
修改表名: alter table 表名 rename to 新表名;
删除约束: alter table 表名 drop index 约束名;
drop table 表名;
create 表名 like 要被复制的表名;(仅复制表的结构)
create 表名 (select * from 要被复制的表名);(复制结构+数据)
若只复制部分数据或结构,在查询中加入筛选或者只填入部分字段即可
只复制部分字段并且不复制数据时,可在where子句中添加永为假的筛选条件(1=2)
事务控制语言
一个或者一组SQL语句组成的执行单元称为事务
这些语句要么全部执行,要么全部不执行
如果某一条语句出现了错误,那么整个单元会进行回滚,将数据状态返回到事务开始前的状态
innodb, myisam, memory
innodb支持事务, myisam和memory不支持事务
1、原子性:事务是一个不可分割的工作单位,事务中的操作要么全部发生,要么全部不发生
2、一致性:事务必须时数据库的一个一致性状态转换到另一个一致性状态
3、隔离性:一个事务执行时,其内部进行的操作对其他事务是隔离的,是不能被干扰的
4、持久性:一个事务一旦被提交,那么它对数据库的改变是永久性的
隐式事务:事务没有明显的开启和结束标记(insert,update,delete)
显示事务:事务有明显的开启和结束标记
前提:先设置自动提交功能为禁用(set autocommit = 0)
开启事务:begin
编辑事务中的语句(这里通常都是对数据进行操作的语句,而并非对表和库进行操作)
[设置保存点:savepoint a]
回滚或者提交:rollback[ to a] or commit
脏读:一个事务没有提交,另一个事务使用了未修改的数据
不可重复读:一个事务多次访问但没有修改数据的时候,另一个事务进行了修改,导致事务一都到了不一致的数据
幻读:一个事务对一张表中的全部数据修改之后,另一个事务进行了插入数据,当第一个事务进行查询是,发现了为修改的数据
脏读 不可重复读 幻读
read uncommitted √ √ √
read committed × √ √
repeatable read × × √
serializable × × ×
MySQL中默认为repeatable read
查看隔离级别:select @@tx_isolation
设置隔离级别:set session|global transaction isolation level 隔离级别;
1、开启事务
set AUTOCOMMIT=0;
begin;
2、编辑事务中的语句
insert into t1 (name) value(‘1’);
insert into t1 value(1,‘ltt’);
3、结束事务
commit;
select * from t1;
有系统提供,属于服务器层面
查看所有系统变量:show global | [session] variables;
查看部分系统变量:show global | [session] variables like '······';
查看某个系统变量的值:select @@global | [session].系统变量名;
为某个系统变量赋值:set global | [session] 系统变量名 = 值;
set @@global | [session].系统变量名 = 值;
全局变量需要加global,会话变量加session,默认为session
仅仅针对当前会话有效。
用户自定义的变量,不属于系统
作用域:针对当前会话有效,同于会话变量的作用域
声明并初始化:
set @变量名 = 值;
set @变量名 := 值;
select @变量名 := 值;
赋值: 方式一:同初始化
方式二:select 字段 into 变量名 from 表名;(查询并赋值)
查询内容:select @变量名;
作用域:在定义该局部变量的begin-end中有效
声明:
declare 变量名 类型;
declare 变量名 类型 default 值;
赋值:select 字段 into 变量名 from 表名;
含义:虚拟表,和普通表一样使用
语法:
create view viewName
as
select···············
use world;
create view mostPopulation50
as
select *
from city
order by population desc
limit 50;
select * from mostPopulation50;
create or replace view viewName
as
select···········
意为如果视图不存在(视图名不重复),则创建视图
如果视图存在,则就修改视图
alter view viewName
as
select·················
drop view viewName1, viewName2, viewName3·····
更新的是基本表中的数据,而不是只更改视图
具有以下特点的视图不能更新:
1、包含以下关键字:
分组函数,distinct,group by,having,union,union all
2、常量视图
3、select中包含子查询
4、join
5、from一个不能更新的视图
6、where子句中的子查询引用了from子句中的表