一、MySQL
MySQL是一个“客户端-服务器”结构的程序
客户端(client):主动发起请求的一方
服务器(server):被动接受请求的一方
请求(request)客户端主动给服务器发的数据
响应(response)服务器给 客户端返回的数据
客户端和服务器不是一成不变的(看场景)这只是一个相对的情况
如图中所示:
如果x向y发送请求,x便是客户端,y便是服务器
如果y向z发送请求,y便是客户端,z便是服务器
mysql是关系型数据库
关系型数据库都是用表的形式组成的
MySQL组织形式:
数据库(数据集合)->数据表->行->列
一个MySQL服务器上,可以有很多歌数据库
每个数据库里,可以有很多个数据表 ->把一些有关联关系的表放到一起
每个数据表里可以有很多行
每个行中可以有很多列
一个sql的大概执行顺序:
1.遍历表
2.带入条件
3.计算列名中的表达式(定义别名)
4.排序/聚合等操作
二、数据库的操作
1、库操作
要实现数据库的操作,我们先建立一个数据库
我们会在2.2中有说明
1.查看现有的数据库
show databases;
输入上述指令后,会输出我们所有的数据库,包括mysql自带的数据库,这些数据库是自带的,如果我们删除这些数据库,我们的数据可能会出现问题。
2.创建数据库
create database +数据库名;
注意:我们不能使用关键字做数据库名,如果需要加上反引号(`)
在创建数据库的时候还可以制定字符集:
create database +数据库名 charset +字符集名;
汉字表示的字节由编码方式来决定:
主流就两种:
gbk :使用两个字节表示一个汉字
utf8(更广泛) :变长编码,对于汉字来说一般来说是3个字节
utf8不仅仅能表示汉字还能表示世界上的语言文字,两个都兼容ASCII。
但是我们要知道的是,在mysql中的utf8是不完整的,少了一点东西(是没有emoji的),要使用完整的utf8,mysql提供了utf8mb4,这是mysql独有的。
3.使用数据库(选中数据库)
后续进一步操作都是需要先选中,再操作
use +数据库名;
不管是什么,我们对数据库操作都需要选中数据库
接下来的操作都是针对被选中的数据库进行的
在存在多个数据库的情况下,这样的设定是非常有用的。
4.删除数据库(删除数据库非常危险)
drop database+数据库名;
这是一个非常危险的操作,一旦删除,这个数据库会消失不见,不能恢复。
2、数据类型
在了解表操作之前,我们要了解sql中的数据类型:
1、整型和浮点型
注意:float(M,D),单精度,M指定长度,D指定小数位数,会丢失精度
2.日期类型
3.字符串类型
3.表操作
1.查看表
show tables;
我们没有创建表,所以我们查询的时候查询不到。
2.创建表
create table 表名(列名 类型 约束类型,列名 类型 约束类型,列名 类型 约束类型,......);
这我们就简单的建立了一个学生表
ps:名字在前,列名在后 在同一个数据库中 表明不能重复(不同数据库中互不影响)
我们先了解一下约束:
数据库的约束:约束可以理解成,数据库提供的一种针对数据的合法性,验证的机制(如果数据库不提供这样的校验机制,就只能靠程序员手工来保证,数据是靠谱的)。
六种约束类型
not null :
设定not null 说明列里不能存储空值,表里的这个内容就是必填想项.
unique :
保证每列的每行必须有唯一 的值,设定这一列所有行的数据都得是唯一的.不能重复.每次插入/修改,都要先出法查询.如果当前插入/修改值已经存在,就会插入/修改失败
default :
规定没有给列赋值是的默认值.(default ' 默认值');
指定默认值 不进行任何指定,默认值是null 在指定列插入的时候会用
primary key:
not null 和unique 结合 确保某列(或者两个列多个列结合)有助于更容易快速地找到表中的一个特定的记录
一个表只能有一个主键(怕出现二义性)
(primary key auto_ increment)
(自增主键,本质上是mysql服务器存储了当前表中的最大id,再进一步的进行累加的)
例如 插入100 删除了100 它自增还是 101
*foreign key :
保证一个表中的数据匹配另一个表中的值的参照完整性
当前表的列 引用自哪个表哪个列。
foreign key (列名) references 表名(列名);
将另一个表的某列作为外键
此时两个表建立了联系 当前表的值 必须在引用表中真实存在(且在父表中确保唯一性 要么是主键,或者是unique)
一旦建立好外键约束,后续针对子表进行操作,就会频繁的涉及到在父表中针对被引用的列,进行查询操作
我们将 引用的表成为父表(parent table) 当前表被制约的表称为(子表)
外键涉及到俩个表之间的关系
当修改外键约束的值时 也要在合法范围内。
一旦父表子表建立联系,要删除只能从子表删除后才能删除父表
check:
保证列中的值复合指定的条件.
check 指定条件,插入/修改数据,数据符合条件才能插入/修改成功,不符合条件,直接失败.
比如 通过check 制定本条件(gender =' 男'or gender = '女');
ps:
1.数据库中,针对主键/unique,查询操作都是有额外的优化策略的,使这里的查询效率比较高(比遍历表要更高)
2.当某个列集合了not null 和unique 就成为了主键
3.查看表结构
desc 表名;
查看表结构我们可以看到我们表中的结构,列的名称,约束条件,可以看到,id是主键,不能为空.......等等
数据库中的null表示的是“这个单元格,没填”(表示可以不填写,默认为空)
4.删除表
4.删除表
drop table 表名;
不仅仅是删除表的本身,也删除了表里面的数据;
这里便不演示!!!
————————————————
在进入重中之重前我们在这说一下mysql中的注释
comment 注释 :这个注释只能用在创建表的时候,声明列的注释
更推荐使用‘#’作为注释或者使用“-- ”作为注释
在sql中的重中之中便是CRUD
即增删改查
5.增删改查
1.增
a.新增
insert into 表名 values(值,值....);
这里的数量类型都要和定义的表头相匹配
ps:这里要指定的字符串:SQL ' ' ,""都可以表示字符。
与java中有些许不同,取决于编程语言是或否支付“字符类型”
ps:sql是一个弱类型语言,会进行隐式类型转
比如,‘ 100’是一个字符/串,在进行计算的时候mysql会试着把‘100’转换成数字100,进行计算
——————————
题外话:
静态类型和动态类型 :
一个变量的类型,能否在程序运行过程中发生改变!
不许允许改变的就是静态类型(c,java)
允许发生改变,就是动态类型(python,js)
b.指定列插入
(这里的列名,个数和顺序就不需要和表头信息一直,但是要保证列名是否被存在)
insert into 表名(列名,列名) values(值,值,值);
这里我们便插入了三条数据(id为空,便是因为我们开始建立表的时候使用了自增主键)
我们现在查看表:
可以看到null的id自动添加了,自增长.
c.一次性插入多行数据
inset into 表名 values (值,值,值....),(值,值,值).......;
这种插入方式也是允许的,在工作环境中不可能一条一条数据慢慢插入,这种方式可以快速增加数据.
——————————
关于插入时间是有固定的格式的
'datetime'
datetime(有固定格式)-> (年-月-日-时-分-秒)-('2024-02-28 21:12:00');
有时候插入的数据要指定的实践,就是当前系统时间
sql作为编程语言也提供了一些库函数(new())
————————————————————————
2.查询
a.全列查询
select *from 表名;
ps: *为通配符;
这是最简单的查询,也是非常危险的操作,一但数据量过大,会占用过多的带宽,会让数据库崩溃
b.指定列查询
select 列名,列名.....from 表名;
ps:(可以指定先后顺序;确保列中存在,要查询哪些列才会真正返回对应的列)
在上面我们介绍了 '*'是一个通配符,只要将通配符改成我们需要查询的列即可,在这里我只指定一个列:
select name from students;
c.表达式查询
select 列名,表达式(+ - * / )from 表名;
(查询的结果不仅仅是列,而是可以把列带入到表达式中进行计算)
在我们建立的表中有score,和id,我们试着计算一下,这里的计算没有任何意义 只是距离,建表的时候考虑欠佳
select name,id + score from students;
我们可以看到列名为 id + score 这一列,就是我们和id相加的结果,其实我们可以给这个列进行自主命名(就是我们说的起别名),其实表也是可以起别名的我们在多表查询的时候会涉及到,这里我们不过多介绍.
话不多说上代码:
select name,id + score as totle from students;
可以看到我们列名变成了totle.
ps:sql中进行算数运算的时候,如果其中某个操作数是null,最终的结果也是null。
我们新增一个成绩为空的例子让大家更明显的看到
insert into students values(null,'王六',null);
select name,id + score as totle from students;
可以看到 '王六'这一栏计算的结果为null.
*表达式查询,计算的时候,可以多个列一起参与计算.
这里并不多介绍,感兴趣可以自己实践.
————————————————————
说到这里,我们要明白的是
上面的表达式查询只是针对服务器响应得到的临时结果进行了计算,不影响硬盘上存储数据本身.
d.去重查询
select distinct (列名) from 表名;
distinct (针对查询结果进行去重,存在重复数据,就会把重复的行合并成一行)
可多列(会变成 两行的这两个列都相同,才算重复)
例如:
select distinct 列名,列名 from 表名;
举个例子:
我们先插入两个相同的数据:
insert into students values(null,'王六',null),(null,'王六',null);
在插入一个略有不同的数据:
insert into students values(null,'王六',80);
查看表的数据为:
我们使用去重查询name为的结果:
我们使用去重查询'name','score',的结果
这样我们知道,在使用distinct的时候,显示多个列的条件是,显示的列都一致时才能去重
————————————————
e.排序查询
select *from 表名 order by 列名;#(这里的排序都是按照行为单位进行排序的)
select的查询结果默认是无序的,要想让查询的结果'有序'必须手动使用order by语句,让mysql主动排序。
null 视为最小值,如果存在多个null,顺序不确定
select *from 表名 order by 列名 desc;
加上desc 表示升序排序。
order by后面写的表达式不一定非要在 select 列名这里出现,不一定非要显示,只按照by后面排序也可以(可以理解为我只是用你来排序,但是我不会显示你)
我们全列查询是这样的,是无序的,在后面可以看到王四会到第三位.
select id,name from students order by score desc;
这里可以看到,我们只是把socre当做一个排序规则,并没有显示她所在的列(工具人)
by后面可以跟别名
select 列名,列名+列名(表达式) as total from 表名 order by total;
我们看到这样也是可以的,total就是前面所起的别名(在使用聚合查询的时候使用比较好,这里的操作并无实际意义)
order by 也是可以指定多个列排序,通过多个列排序约定更复杂的比较规则
select *from order by 列名[desc],列名[desc]......
列名越靠前优先级越高,可以看到我们是把score放在order by的后面,在name的前面,我们这里是使用降序排序,先按照score列的大小比较,如果发现大小一致,在比较后面的列,(字符串)有自己的比较规则,不多赘述,所以,列名越靠前,优先级越高,如果全部都一致,前后顺序将随机.
f.条件查询
[最重要&&最常用]
select*/列名/表达式/去重 from表名 where 条件;
在了解条件查询前,我们应该了解一下操作符,如下:
比较运算符:
## 我们要注意的是,和大多语言不通的是,这里的 '=' 是比较相等.
## and 的优先级是优先于or的
还要注意的是:
null和其他的值进行关系运算结果也是null
这里我们先看
1)基础的查询:
简单举个例子,在我们上述创建的表,查看成绩 >80 成绩的人
可以看到我们的查询结果会排除成绩为NULL的结果和刚好为80的结果:
select *from students where score > 80;
我们再查询结果为score为80和null的结果:
其他的比较运算符就不一一举例了,都是一样的表达方式,我们接着往下
2)范围查询
说到范围查询我们不得不提 between和in了
1.between ....and
在这个范围之内的数据:
举个例子:
我们查询80-90之间的数据
select *from students where score between 80 and 90 ;
2.in
和上述的between and相比,in查询的是具体的数据,或者说是间断的数据
举例
select *from students where score in(80 ,88);
##在编程中谈到"区间"大概率都是前闭后开区间,少数情况是闭区间,开区间/前开后闭区间基本看不到
3)模糊查询
(= 是精确查询,要求查询的结果和条件中指定的内容完全一致)
select 列名 from 表名 where (条件) like '...%';
like 模糊查询不要求完全一致,只要一部分一致即可
like有自己的通配符:
%: 匹配任意个字符(可以是0个字符):
举个例子,我们查询一个姓名为王的同学:
1.王%
表达的意思是以王字开头的name
select *from students where name like '王%';
于我设计的表过于简单,所以我们添加多几个数据,方便理解:
添加的数据:
添加后的数据后查询的结果:
2.%王
以王字结尾的name:
3.%王%
以王字在...王...都可以 不管前后的字是1 2 个,不限制字数(也可以是没有字)
查询的结果:
_:匹配一个字符
1.王_
往后只能匹配一个字符
通俗的来说就是只能姓王,且只能取名为两个字
查询的结果:
2._王
通俗的来说,只能查询王字结尾,且字数限制在两个字
select *from students where name like '_王';
查询结果为:
3._王_
通俗的来说就是中间的字只能是王,且限定字数为三个
select *from students where name like '_王_';
所以我们的查询结果只有一个,和%王%,有着明显的区别:
4)针对null的查询
有以下几种情况,看使用的运算符,运算符的不同结果也会不同
1.null = null ->false
2.null <=> null->ture
#适用性更广 可以进行两个列之间的比较
is [not] null
同样是null,视为相等,还是不相等,要根据实际的场景来灵活调整
5).分页查询- limit
select * from 表名 limit 3 ; #获取前三条数据
limit 关键字来进行描述 限制了这次查询最多 返回多少记录
后搭配offset 成为偏移量 (若不加offset 默认偏移量为0)
select * from 表名 limit 3 offset 3 ;#从第三个数据开始显示数据
还有一种 写法
select *from 表名 limit 6,3; 6相当于offset ,3为最大条数;
在这里简单举一个例子:
我们也可以吧经过排序之后再把数据显示
不过要把limit放在最后
select *from students order by score desc limit 3 ;
举例:我们只显示score最高的前三位
h.插入查询结果
insert into 表名(要插入的表名) select *from 表名(被插入的表名);
需要确保查询的结果集合,列数/类型,要和插入的列数类型匹配(列名是否一致无所谓,但是顺序一定要匹配,不匹配,即类型可能不一致)
这里为了方便演示
我们在再建立一个空表,方便我们演示:
desc students;//我们先查询我们所建立的表的属性,确保数据类型的一致(名字是否一致我们不关心)
create table students2(id2 int,name2 varchar(25),score2 double);建立一个类型一致的表
insert into students2 select *from students;
select *from students2;//现在查询数据是否插入成功
我们可以看到数据插入成功了
i.聚合查询
我们要知道,聚合查询是行与行之间的运算
首先我们先要了解的是聚合函数:
1)count([distinct] expr)
返回查询到的数据的数量
select count(*) from students;
如果我们count()针对的是某一列,那返回的行数会跳过为null的数据
这里并不举详细的例子(因为王六的数据在下面为空的数据在下面删除举例删掉了,为了把查询的全部整合在一起)(还有就是这个博客写到这已经花了三天时间了请一定三连)
如果count(*),那代表查询的是全部数据,null的数据也会被记录其中
ps:
1.count可以帮我们获取到非空记录数量
2.count 还可以搭配group by 进行分组(后面会讲)
2)sum(distinct expr)
返回查询的数据的总合,不是数字没有意义
select sum(列名)/表达式 (as 别名) from 表名;
这里我们可以把表中score的数据进行计算并取个别名为sum (没有指定别名正常来说是sum(score)):
select sum(score) from students;
ps:count 可以(*),但是sum不能sum(*),sum这个涉及相相加,相当于针对所有的列,每个列都分别相加(有些列不是数值) 若对非数值的数据相加 不会报错但是会报警告
3)avg([distinct] expr)
返回查询的数据的平均值],不是数字没有意义
select avg(列名) from( 表名);
可以搭配其他聚合函数使用:
select avg(列名),sum(列名) from( 表名);
我们同样用score举例:
4)max([distinct] expr)
返回查询的数据的最大值,不是数字没有意义
使用max查询score的最大值:
select max(score) from students;
5)min([distinct] expr)
返回查询的数据的最小值,不是数字没有意义
使用min查询score的最小值:
select min(score) from students;
j.分组查询
select 列名1, count(列名2) from 表名 group by(根据分组的)(列名1);
为了方便演示我们构建一个新的表:
我们有name(名字),role(职位),salary(薪资)
insert into emp(name, role, salary) values
-> ('马云','服务员', 1000.20),
-> ('马化腾','游戏陪玩', 2000.99),
-> ('孙悟空','游戏角色', 999.11),
-> ('猪无能','游戏角色', 333.5),
-> ('沙和尚','游戏角色', 700.33),
-> ('隔壁老王','董事长', 12000.66);
我们试着用职位进行分组查询并分组查询:
select count(role),role from emp group by role;
我们再试着计算一下职业的平均工资:
select count(role),role,avg(salary) from emp group by role;
我们再试着把不相关的列加入进来,我们会看到我们得到了一堆无效的数据:
##
1)所以我们要知道的是,非group by 的列不应该直接写到select 查询的列中(如果是聚合函数那是可以的)不然,数据将会没有意义.
2)我们还要知道分组之后的顺序不可知 除非使用order by;
最后我们还要了解一个关键词having,他的含义是对分组后的条件进行指定条件
举个例子:我们计算salary的平均值,并过滤掉<1000的数据(显示>1000的数据)
select count(role),role,avg(salary) from emp group by role having avg(salary) > 1000;
我们在这可以计算一下总的平均工资,但是工资过高的董事长(隔壁老王)我们想显示>700的数据
这里我们便需要使用where,在分组前将 name = '隔壁老王'的数据排除,结合having使用
select role,avg(salary) from emp where name != '隔壁老王' group by role having avg(salary) > 700 ;
k.联合查询/多表查询
1)内连接
为了更好演示,我们重新建立一个表.
由于建立一个表的过程过于繁琐,我直接借鉴某某课件上的数据
classes(id int primary key auto_increment,name varchar(20),`desc` varchar(100));
create table student(id int primary key auto_increment,sn varchar(20),name varchar(20),qq_mail varchar(20),classes_id int);
create table course(id int primary key auto_increment,name varchar(20));
create table score(score decimal(3,1),student_id int,course_id int);
insert into classes(name, `desc`) values
-> ('计算机系2019级1班', '学习了计算机原理、C和Java语言、数据结构和算法'),
-> ('中文系2019级3班','学习了中国传统文学'),
-> ('自动化2019级5班','学习了机械自动化');
insert into student(sn, name, qq_mail, classes_id) values
-> ('09982','黑旋风李逵','xuanfeng@qq.com',1),
-> ('00835','菩提老祖',null,1),
-> ('00391','白素贞',null,1),
-> ('00031','许仙','xuxian@qq.com',1),
-> ('00054','不想毕业',null,1),
-> ('51234','好好说话','say@qq.com',2),
-> ('83223','tellme',null,2),
-> ('09527','老外学中文','foreigner@qq.com',2);
insert into course(name) values
-> ('Java'),('中国传统文化'),('计算机原理'),('语文'),('高阶数学'),('英文');
insert into score(score, student_id, course_id) values
-> -- 黑旋风李逵
-> (70.5, 1, 1),(98.5, 1, 3),(33, 1, 5),(98, 1, 6),
-> -- 菩提老祖
-> (60, 2, 1),(59.5, 2, 5),
-> -- 白素贞
-> (33, 3, 1),(68, 3, 3),(99, 3, 5),
-> -- 许仙
-> (67, 4, 1),(23, 4, 3),(56, 4, 5),(72, 4, 6),
-> -- 不想毕业
-> (81, 5, 1),(37, 5, 5),-- 好好说话
-> (56, 6, 2),(43, 6, 4),(79, 6, 6),
-> -- tellme
-> (80, 7, 2),(92, 7, 6);
会得到四张表分别是
1.班级表:
2.学生表:
3.学科表:
4.成绩表
select *from 表1,表2;
我们以上述数据为例,比如查询学科表和学生表的笛卡尔积:
可以看到这数据是他们数据总和的乘积,并且我们会看到非常多的数据,一个屏幕都无法完全显示.
(所以我们在实际的开发中要谨慎使用,数据过于庞大会消耗更多的资源,和网络带宽,会是数据库崩溃)
我们将这样查询得到的结果称之为,笛卡尔积
表名的顺序不关键,哪个记录在前在后都可以并且也可以通过order by 来排序
笛卡尔积是全排列过程,在尝试穷举出所有的可能性,自然就产生一些不符合实际情况的数据,数据不能反映客观事实的 ,这个数据就是无效的,所以,需要某种条件进行剔除不符合客观事实的数据,这种专门帅选出有效数据的条件也称为"连接条件"(连接操作)
所谓的连接条件,应该是某个列,再俩个表中,同时都存在~~如果不存在这样的两个表中同时存在的列,可以认为此时的笛卡尔积是没有意义的
所以我们真正的语法是:
select */许多列名from 表1 别名,表2 别名 where 连接条件 and 其他条件;
或者是另一种写法:
select */许多列名from 表名1 别名1 join 表名2 别名2 on 连接条件 and 其他条件;
我们以上面这个表来查询:
所有同学的成绩和同学们的个人信息:
一般会有这几个步骤分析题目:
(这篇博客是偏向基础的,我们试着将题目拆解,而不是一下子马上就把代码编写出来)
1.先确定要查询的信息来自于哪个表
成绩来源于socre表
学生信息来自student表
成绩会有科目名,所以我们要加上一个course表(很容易忽略)
2.针对这几个表进行笛卡尔积
select *from studen student,score,course;
3.加上连接条件,去除无效数据
根据每个表的相同条件来获取连接条件
1.student表中id 是与 socre 表中的studen_id是一致的
2.score表中的course_id适合course表中的id一致
我们以此为链接条件就可以得到我们的笛卡尔积表:
select *from student as stu join score as sco on stu.id = sco.student_id join course as cou on sco.course_id = cou.id;
4.再根据实际要求补充其他条件(聚合条件)
根据题目并没有其他条件,直接跳过
5.把不必要的数据剔除
我们可以看到题目要求是要学生的信息,还有成绩,学科名称,所以其他我们是可以直接剔除的
select stu.id,stu.sn,stu.name,stu.classes_id,sco.score,cou.name from student as stu join score as sco on stu.id = sco.student_id join course as cou on sco.course_id = cou.i
d;
得到的最终结果为:
---------------------------------------------
使用集合的方式没表示内连接:
2)外连接
只能使用join on的方式写(left/right关键字)
left连接:
select *from 表名1 left join 表名2 on 连接条件;
right连接:
select *from 表名1 rgiht join 表名2 on 连接条件;
"左外连接"和"右外连接"
左外连接: 右边的数据会使用null来填充
右外连接:左边的数据会使用null来填充
上述的表,可能大家没有注意到
"老外学中文""这个这个人的数据,在内连接查询笛卡尔积的时候是没有显示出来的,因为他的成绩为空,在和成绩表进行笛卡尔积是没有现实的,我们这时候试试外连接,是可以把她的成绩以null的形式显示出来的
select *from score right join student on score.student_id = student.id;
使用集合的方式来表示各种连接方式:
使用集合的方式来表示外连接:
3)自连接
自连接: 同一个表自己和自己计算笛卡尔积(自连接能够把行之间的关系转换成列之间的关系)
#但是,自连接的时候,为了转换成上述的列关系,产生大部分中间结果都是不必要的.
直接进行自连接不可取,但是表名也可以取别名,(和上述一样);
select *from 表名1 别名,表名1 别名 where 连接条件 and 其他条件;
或者:
select *from 表名1 别名 join 表名1 别名 on 连接条件 and 其他条件;
假设我们这里要查询"java""的成绩比"计算机原理"高的成绩:
我们在成绩表知道他们是两个行之间的比较的数据,所以我们要考虑自连接
1.我们先查询一下他们course的id
select *from course where name = 'java'or name = '计算机原理';
查询到他们的id分别为1和3
2.根据查询的id作为条件进行自连接
select *from score s1,score s2 where s1.student_id = s2.student_id and s1.score > s2.score and s1.course_id = 1 and s2.course_id = 3;
4)子查询
把多个sql嵌套成了一个sql
也称为嵌套查询
1.单个数据的子查询:
比如我们查询student中许仙同学的同班同学
按我们正常的思维是:
1)先查询许仙同学的班级id
2)然后再根据班级id查询
而子查询会将这两步合起来,一步到胃
select *from student where classes_id = (select classes_id from student where name = '许仙');
2.多个数据的查询
我们查询java合并计算机原理的成绩信息.
直接一步到胃(过程是和上面一致的)
select *from score where course_id in (select id from course where name = 'java'or name = '计算机原理');
5)合并查询
(把多个查询结果集合,合并在一起)
union(允许你从多个不同的多个表分别查询,只要表查询的结果集合列的类型和个数匹配,都能合并
union默认是去重的,如果不需要去重,就需要使用union all
select *from course where 条件 union select *from course(同类型表) where 条件;
union:
在course表中查询name为英文和id>1的数据
select *from course where name = '英文' union select *from course where id > 1;
union all:
select *from course where name = '英文' union all select *from course where id > 1;
可以看到.加上all之后没用去重,all会重复出现
or 只能针对一个表,合并查询适用于多个的查询
不用说,or这样是不会出现重复的数据的
还要注意的是也可以和不同的表,只需要保证字段的一致(列数,数据类型等等)
由此我们可以总结:
合并查询只是把最后的结果集合进行合并,整体的过程其实和执行多个sql没区别
子查询是带入到条件中,形成了更复杂的"嵌套结构".
3.修改操作
(update 会修改服务器硬盘上的数据)
update 表名 set 列名 = 值 where 条件;#(可以进行多个列进行修改 )
#原则上来说匹配到的行都要修改 ,但是有些时候,比如修改的值是非法的值,修改失败,此时,修改成功的行数(changed)就会少于匹配的行数(matched).
1.修改也可以借助一些表达式(+-*/);
2.搭配 limit order by使用
3.update 表名 set = 值 order by 排序条件 limit (显示页数);
针对上面的三个,我们针对score为null的数据进行修改:
根据order by排序,null是最小值会排到前面,我们使用limit筛选数据,我们再使用+-*/修改数据:
update students set score = 70 where score is null order by score limit 3;
我们现在查看数据:所有为空的数据都被修改成了70
我们再将70增加:
update students set score = score + 10 where score = 70;
我们可以看到70的数据修改成了80.
如果update 不指定任何条件,相当于条件都为真,会将数据全部篡改
6.删除
delete
delete from 表名 where 条件; #数据一旦删除无法恢复
前面我们有很多个name为王六的数据
我们试着把他删除:
delete from students where name = '王六';
我们可以看到王六的数据被全部删除了.
#如若不指定条件,会把全部数据删除,只是删除了数据.把表编程了空表;
____________________________________________
文章到这里就结束了,由于篇幅过长,会出现错别字,还有很多问题,不能及时发现,如有错误请指正!!!!!!!!
爆肝了1w多字,求三连!!!!