关于MySQL和MySQL中的各种操作

一、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多字,求三连!!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值