MySQL语句 - sql语句

  • sql 语句介绍
    • MySQL中如何求帮助
  • sql语句的基本操作
    • 前置知识
    • 数据库的基本操作
    • 数据表的基本操作
    • 数据的基本操作
    • 自动增长(水位线)与主键约束
  • 数据类型
    • 整数类型
    • 小数类型(浮点类型、定点类型)
      • 浮点类型(近似值)
      • 定点类型(精确值)
    • 字符串 类型
      • char 类型 (定长)
      • varchar 类型(变长)
      • text 类型(文本)
      • 其他字符串类型
    • 日期时间 类型
  • SQL查询五子句
    • WHERE 条件子句
    • DISTINCT 数据去重子句
    • GROUP BY 子句
    • HAVING子句
    • ORDER BY子句
    • LIMIT子句
  • SQL多表查询
    • UNION联合查询
    • 交叉查询
    • 内连接查询
    • 外连接查询
    • 别名机制:简化内外连接

sql 语句介绍

什么是sql 语句?

SQL(Structure Query Language)是 结构化查询语句的缩写,它是使用关系模型的数据库应用语言,由 IBM 在 20 世纪 70 年代开发出来,作为 IBM 关系数据库原型 System R 的原型关系语言,实现了关系数据库中的信息检索

20 世纪 80 年代初,美国国家标准局(ANSI)开始着手制定 SQL 标准,最早的 ANSI 标准于1986 年完成,就被叫作 SQL-86。标准的出台使 SQL 作为标准关系数据库语言的地位得到了加强。SQL 标准目前已几经修改更趋完善

正是由于 SQL 语言的标准化,所以大多数关系型数据库系统都支持 SQL 语言,它已经发展成为多种平台进行交互操作的底层会话语言

SQL语句的分类:

DDL(Data Definition Languages)语句:

  • 数据定义语言这些语句定义了不同的数据段、数据库、表、列、索引等数据库对象的定义。常用的语句关键字主要包括 createdropalterrenametruncate

DML(Data Manipulation Language)语句:

  • 数据操纵语句,用于添加、删除、更新和查询数据库记录,并检查数据完整性,常用的语句关键字主要包括 insertdeleteupdate

DCL(Data Control Language)语句:

  • 数据控制语句,用于控制不同数据段直接的许可和访问级别的语句。这些语句定义了数据库、表、字段、用户的访问权限和安全级别。主要的语句关键字包括 grantrevoke

DQL(Data Query Language)语句:

  • 数据查询语句,用于从一个或多个表中检索信息。主要的语句关键字包括 select

MySQL中如何求帮助

通过官方文档查看:软件安装下载说明

MySQL5.6官方文档

MySQL5.7官方文档

通过man文档查看:软件命令说明

  • man文档可以对mysql的一些基本工具及后台命令求帮助
查看命令说明:# man mysql    # man mysql_install_db# man mysqldump# man mysqld

MySQL的命令行求帮助:主要针对SQL语句说明

  • 需要进入mysql
  • 在mysql内部,没有clear命令,也就是无法使用clear实现清屏,如果想实现清屏操作,可以使用快捷键Ctrl + Shift + L
进入mysql:# mysql -uroot -p通过help或?查看帮助:mysql> ? 或   mysql> help;     =>  查看命令帮助如果想深入了解sql语句的增删改查:mysql> help contents; 备注:出来啥选项就在前面加个'? 选项'进一步查看帮助即可,会显示相关语法

sql语句的基本操作

前置知识

MySQL内部结构:

我们平常所说的MySQL其实是MySQL数据库管理软件

一个MySQL DBMS 可以同时存放多个数据库,理论上一个项目对应一个数据库。如:博客项目的blog数据库、商场项目shop数据库、微信项目wechat数据库等

一个数据库还可以同时包含多个数据表,数据表才是真正用于存放数据的位置。理论上一个功能就对应一个数据表。如:博客系统中的用户管理功能,就需要一个user数据表、博客中的文章就需要一个article数据表、博客中的评论就需要一个message数据表

一个数据表又可以拆分为多个字段,每个字段就是一个属性(对应其功能的位置,如user表中的username、passsword字段)

一个数据表除了字段以外,还有很多行,每一行都是一条完整的数据(记录)

数据库和表的操作:

show 查询数据库或数据表
database 数据库
databases 所有数据库
table 数据表
tables 当前数据库下所有数据表
use 使用一个数据库
create 创建数据库或数据表
alter 修改数据库或数据表的编码格式,修改数据表名称,对数据表的字段(增删改)或字段类型(改),修改数据表的引擎
drop 删除数据库或数据表

数据的操作:

insert 对数据表插入记录
delete 删除数据表的记录
update 修改字段的值
select 查询某个数据表记录

编码格式:

latin1 MySQL数据库默认的编码格式是latin1 (拉丁文)编码格式,最大只有256个字符
gb2312 和 gbk 因为中国汉字无法通过256个字符进行描述,所以早期开发个自己的编码格式gb2312(不兼容繁体), 后期升级为gbk(兼容繁体),用两个字符组合成为一个汉字
big5 中国台湾因为早期gb2312不兼容繁体,所以自己开发了一套编码格式big5
utf8 和 utf8mb4 标准化组织开发了一套多国通用的编码utf8(也称万国码),后来MySQL5.6版本以后又升级为utf8mb4(真正的UTF-8编码)

数据库的基本操作

  • 在MySQL5 以后的版本中,MySQL不支持更改数据库的名称。我们所谓的修改数据库主要修改的是数据库的编码格式

  • 创建数据库时,如果不指定字符集则默认使用MySQL的字符集latin1

  • default character set utf8 = default charset=utf8,两者用法一样

数据库的增删改查:

创建数据库:create# mysql > create database 数据库名称;                   =>  创建一个数据库#    mysql > create database 数据库名称 default charset=编码格式;     =>  创建数据库 并指定默认字符集演示:create database db_blog;                        =>  创建数据库不指定编码格式,默认使用latin1编码格式create database db_blog default charset=gbk; =>  创建数据库并指定gbk编码格式判断数据库是否已创建:if not exists# mysql > create database if not exists 数据库名称 default charset=编码格式    =>  数据库不存在则创建,存在则给出一个警告提示演示:create database if not exists db_shop default charset=utf8;查询数据库:show#    mysql > show databases;                  =>  显示所有数据库#    mysql > show create database 数据库名称;      =>  显示某个数据库数据库的数据结构修改数据库的编码格式:alter# mysql > alter database 数据库名称 default charset=新编码格式;     =>  将某个数据库的编码格式修改为utf8演示:alter database db_blog default charset=utf8;删除数据库:drop# mysql > drop database 数据库名称;         =>  删除某个数据库指定数据库:use#    use 数据库名称;          =>  使用某个数据库

数据表的基本操作

  • 创建数据表时,最后一个字段结尾是没有逗号,

  • 创建数据表前需要先指定某个数据库mysql > use DB_name,才能够在指定数据库下创建数据表

  • 在MySQL 5.6以后的版本中,MySQL的引擎默认为innodb

  • 创建数据表时如果不更改引擎,默认使用innodb

数据表的增删改查:

创建数据表:create# mysql > create table 数据表名称(字段1 字段类型 [字段约束],字段1 字段类型 [字段约束],...)      =>  创建数据表,并指定字段和类型                   #   mysql > create table 数据表名称(字段1 字段类型 [字段约束],字段1 字段类型 [字段约束],...) engine=引擎 default charset=编码格式;=>  创建一个数据表,并指定其引擎和编码格式演示:create table tb_user(id tinyint,username varchar(20),password char(32)) engine=innodb default charset=utf8;查询数据表:show、desc#    mysql > show tables;                 =>  查询指定数据库下所有数据表#  mysql >  show create table 数据表名称;        =>  显示某个数据表的创建过程(编码格式、字段等信息)      #   mysql > desc 数据表名称;                      =>  显示某个数据表的字段和类型信息修改数据表信息:alter数据表添加字段:add# mysql > alter table 数据表名称 add 新字段名称 字段类型 first|[after 其他字段名称]选项说明:first:把新添加的字段放在第一位after 字段名称:把新添加字段放在指定字段的后面              演示:alter table tb_user add gender enum('男','女','保密') first     =>  将gender 字段添加为tb_user表第一字段alter table tb_user add gender enum('男','女','保密') after id   =>  将gender 字段添加到id字段后面修改字段名称或字段类型:change、modify            修改字段名称与字段类型(也可以只修改名称):#   mysql > alter table 数据表名称 change 旧字段名称 新字段名称 字段类型;       =>  修改字段名称,字段类型改也可不改演示:alter table tb_user change id number varchar(20);      =>  将id字段名称修改为number,字段类型不修改仅修改字段的类型:#    mysql > alert table 数据表名称 modify 字段名称 新字段类型;  =>  修改字段类型演示:alter table tb_user modify number varchar(40);      =>  将number字段类型varchar(20)修改为varchar(40)删除某个字段:drop# mysql > alter table 数据表名称 drop 字段名称;     =>  删除一个字段演示:alter table tb_user drop gender;            =>  删除tb_user表中的gender字段修改数据表引擎(MyISAM或InnoDB): engine=#  mysql > alter table 数据表名称 engine=新引擎;       =>  修改某个数据表的引擎演示:mysql table tb_user engine=myisam;     =>  修改tb_user表的引擎为myisam修改数据表的编码格式:default charset=#    mysql > alter table 数据表名称 default charset=新编码格式;        =>  修改数据表的编码格式演示:alter table tb_user default charset=utf8mb4;           =>  将tb_user表的引擎修改为utf8mb4修改数据表名称:rename、alter移动数据表到另一个数据库并重命名:#  mysql > rename table 数据库名称.数据表名 to 新数据库名.新表名;     =>  将数据表移动到新的数据库下并重命名(也可不更改数据表名)      #   mysql > alter table 数据库名称.数据表名 rename 新数据库名.新表名;      =>  将数据表移动到新的数据库下并重命名(也可不更改数据表名)演示:alter table db_blog.tb_user rename db_wechat.tb_wechat_user;        =>  将db_blog数据库中的tb_user表移动到db_wechat数据库并更名为tb_wechat_user表只重命名,不移动数据库:rename、alter   #   mysql > rename table 旧表名 to 新表名;     =>  重命名数据库表名#   mysql > alter table 旧表名 rename 新表名;  =>  重命名数据库表名演示:alter table tb_user rename tb_host;           => 将数据表tb_user名称更名为tb_host删除数据表:drop#    mysql > drop table 数据表名称;

数据的基本操作

  • 在sql 语句中,除了数字字段类型,其他字段类型的值,都需要使用引号引起来,否则插入数据时会报错
  • 在插入数据时,可以不跟字段名,只要插入的数据与表中字段总数一致即可
  • 在修改字段的数据时,记得添加where子句,不然会将修改字段所有的数据都修改为新值

delete fromtruncate区别:

delete:删除数据记录

  • 数据操作语言(DML)
  • 在事务控制里,DML语句要么commit(成功),要么rollback(失败)
  • 删除大量记录速度慢,只删除数据不回收高水位线(不重新编号,接着删除前的编号,即自动增长约束)
  • 可以带条件删除

truncate:删除所有数据记录

  • 数据定义语言(DDL)
  • 不在事务控制里,DDL语句执行前会提交前面所有未提交的事务
  • 清理大量数据速度快,回收高水位线(high water mark)(重新开始编号,即自动增长约束)
  • 不能带条件删除

数据的增删改查:

数据的增加:insert# mysql > insert into 数据表名称[(字段1,字段2,...)] values (字段1的值,字段2的值,...);       =>  对数据表中的字段插入数据演示:insert into tb_user(id,gender,username,password) values (1,'男','admin',md5('admin666'));insert into tb_user values (1,'男','admin',md5('admin666'));       =>  都是往数据表字段插入一条记录数据的查询: select# mysql > selrct*from 数据表名称 [where 查询条件];      =>  查询某个数据表所有字段数据,还可以指定where子句精确查询某条记录#  mysql > select 字段1,字段2,.. from 数据库名称 [where 查询条件];    =>  精确查询某数据表的某个字段的数据,还可以指定where子句精确查询某条记录演示:select*from tb_user;              =>  查询tb_user表的所有数据select*from tb_user where id=1;     =>  查询tb_user表中id=1字段这条记录select id,username from tb_user;  =>  查询tb_user表中id和username字段的所有数据select id,username from tb_user where password='admin666';      =>  查询tb_user表id和username字段的数据,但是password字段值需得为'admin666'数据的修改:update#  mysql > update 数据表名称 set 字段1=新值,字段2=新值,.. where 更新条件;  =>  修改某表中符合某条件字段的值演示:update tb_user set gender='保密',password=md5('12as') where username='admin';    =>  修改admin用户的密码及性别假设学校需要将去年入学的学生年龄整体更新一次,年龄字段为age,表名为tb_student# mysql > update 数据表名称 set 字段=字段[运算符]数字演示:update tb_student set age=age+1;       =>  该字段所有值就会自身加1数据的删除:delete#    mysql > delete from 数据表名称[where 删除条件];       =>  删除某表中的所有记录或是符合某条件的记录#   mysql > truncate 数据表名称;          =>  清空数据表所有记录演示:delete from tb_user;     =>  删除tb_user表中的所有记录delete from tb_user where id=1;        =>  只删除tb_user表字段id=1的记录

自动增长(水位线)与主键约束

一般情况下,我们在设计数据表时,必须拥有一个类似id主键字段,非空、自动编号、主键约束。

查询数据时通过主键索引能够加快查询速度

自动增长:

  • 创建数据表时定义,一般设置某字段自动增长都会设置其为主键
auto_increment 自动增长(对某个字段进行自动编号)
not null 代表非空约束,这个字段只要是插入数据就必须要有值。如果与自动增长结合插入null就代表它自增长的值
#  myqssl > create table 数据表(字段1 字段类型 not null auto_increment,字段2 字段类型 [字段约束],...);

主键约束(非空、唯一):

  • 插入数据,id位置直接写null即可,不用另外写序号。系统会自动
primary key 代表这个字段数据不能为空,且该字段的数据不能相同
第一种写法:跟在所在字段后面# mysql > create table 数据表(字段1 字段类型 not null auto_increment primary key,字段2 字段类型 [字段约束],...);第二种写法:写到最后面# mysql > create table 数据表(字段1 字段类型 not null auto_increment,字段2 字段类型 [字段约束],...,primary key(id));

default 默认值:

default 约束用于向列中插入默认值。 如果没有规定其他的值,那么会将默认值添加到所有的新记录。 也就是说添加默认值之后该列就会有一个初始默认值,以后无论添加多少数据,只要没有主动改变改列的值那么就会默认该默认值

# mysql > create table 数据表(字段1 字段类型 not null auto_increment primary key,字段2 字段类型 [default 默认值],...);

数据类型

  • 在创建数据表时,必须明确指定字段的名称以及字段的类型

下图为MySQL中sql语句支持的字段类型:

整数类型

应用场景: 人的年龄、考试成绩等等相关的信息都可以使用整数类型进行存储

选择方式: 整数类型的选择主要取决于数值的范围

  • 比如存储中国人的人口信息,可以用INT类型也可以用BIGINT类型,但是在数据库设计原则中,不是越大越好,而是正好满足条件即可。否则浪费磁盘空间

整数类型 存储字节 范围
tinyint 1 -281 ~ 127
tinyint unsigned 1 0 ~ 255
smallint 2 -32768 ~ 32767
smallint unsigned 2 0 ~ 65535
mediumint 3 -8388608 ~ 8388607
mediumint unsigned 3 0 ~ 16777215
int 4 -2147483648 ~ 2147483647
int unsigned 4 0 ~ 4294967295
bigint 8 -2^63 ~ 2^63-1
bigint unsigned 8 0 ~ 2^64-1
mysql> use 数据库名称;
mysql> create table tb_student(id mediumint unsigned not null auto_increment,username varchar(20),age tinyint unsigned,      =>  定义mobile char(11),primary key(id)
) engine=innodb default charset=utf8;

小数类型(浮点类型、定点类型)

浮点类型(近似值)

floatdouble:

  • float和double类型代表近似数字数据值。 float单精度浮点数精确到约7位小数,double双精度浮点数精确到大约15位小数 。类型浮点会随着数值的增大精度会减小(即单精度超过7位或双精度超过十五位选取的是数值的近似值)

举例说明:

  • float(M,D),其中,M表示存储的有效位数,D代表小数点后面的位数;即整数位数+小数部分不能超过M值。

  • 如:colum1 float(7,4),代表你插入为999.00009到cloum1列,那么mysql在存储时会四舍五入变为999.0001插入。

  • double(7,4) :double类型的使用与float类型完全一致,唯一的区别就是占用字节不同且浮点数的精度有所不同。

浮点类型 精度 存储字节 精确性 精确小数位数
float 单精度 4 约7位,超过取近似值
double 双精度 8 低,比float高 约15位,超过取近似值

定点类型(精确值)

decimal 和 numeric:

decimal和numeric 类型的存储精确的数值数据。使用这些类型时,重要的是要保留精确的精度,例如使用货币数据。在MySQL中, numeric被作为decimal来应用,所以下面的举例decimal同样适用于 numeric

应用场景: 多用于货币数据的使用,避免数据存储时失真

举例说明:

  • decimal(M,D),其中,M代表精度,N代表刻度。M表示数值存储的有效位数,N表示小数点后面可存储的位数,即整数位数+小数部分不能超过M值。

  • 如:salary decimal(5,2),代表能够存储五位数和两位小数的任何值,因此可以存储在salary 列中的值的范围-999.99是 999.99

  • 特别注意:
    decimal(M)decimal(M,0)是相等的,存储长度取决于M的值,默认情况下M值为10.刻度为0表示没有小数。

浮点类型 精度 存储字节 精确性 精确小数位数
decimal 高精度 M字节(D+2 , 如果M < D) 直接截取到给定小数位,不取近似值
mysql> use db_itheima;
mysql> create table tb_staff(id smallint unsigned not null auto_increment,username varchar(20),salary decimal(11,2),     =>  定义addtime date,primary key(id)
) engine=innodb default charset=utf8;

字符串 类型

char 类型 (定长)

char 类型的字符串定长,长度范围是0 ~ 255 之间,占用定长的存储空间,不足的部分用空格填充(空格也是占用磁盘空间);读取时删掉后面的空间

应用场景: 用于知道确定字符长度的字段,如:mobile char(11),身份证、 或是密码经过加密存储的数据password char(32)(比如密码经过md5加密后得到一个32位字符串)

存储空间:

  • char(M)类型的存储空间和字符集有关系,一个中文在utf8字符集中占用3个bytes、gbk占用2个bytes、数字和字符统一用一个字符表示。

存储机制:

  • 在不够M长度时,MySQL在存储数据时,需要填充特殊的空格.
字符串类型 存储字节 储存空间 特点
char M字节,1 <= M <= 255 不足部分用空格填充 占用定长的所有空间
mysql> use db_itheima;
mysql> create table tb_admin(id tinyint unsigned not null auto_increment,username varchar(10),password char(32),     =>  定义primary key(id)
) engine=innodb default charset=utf8;

varchar 类型(变长)

varchar类型是变长存储,仅使用必要的存储空间.

应用场景: 主要适合存储长度不固定的字符串信息,如用户名称、产品标题、新闻标题、新闻描述(不超过255个字符,超过建议用text类型)

存储空间:

  • varchar(M)类型的存储空间和字符集有关系,一个中文在utf8字符集中占用3个bytes、gbk统一占用2个bytes、数字和字符一个字符表示。

存储机制:

  • varchar(M)字段存储实际是从第二个字节开始存储,然后用1到2个字节表示实际长度,剩下的才是可以存储数据的范围,因此最大可用存储范围是65535-3=65532字节;

  • 第一个字节标识是否为空.(长度小于255字节,使用一个字节来表示长度;大于255字节使用两个字节来表示长度)。

字符串类型 存储字节 储存空间 特点
varchar M字节 1<=M<=65535 仅使用必要的存储空间,最大可用存储范围是65535-3=65532字节 变长,用1到2个字节表示实际长度
mysql> use db_itheima;
mysql> create table tb_news(id int not null auto_increment,title varchar(80),            =>  定义description varchar(255), =>  定义addtime date,primary key(id)
) engine=innodb default charset=utf8;

text 类型(文本)

text代表文本类型的数据,当我们使用varchar类型存储数据时(早期最大只能存储255个字符,MySQL5版本中,其gbk可以存储3万多个字符,utf8格式可以存储2万多个字符),如超过了varchar的最大存储范围,则可以考虑使用text文本类型。

255个字符以内(包括),定长就使用char类型,变长就使用varchar类型,如果超过255个字符,则使用text文本类型。

应用场景: 文本内容、产品的详细介绍等等

mysql> use db_itheima;
mysql> create table tb_goods(id int not null auto_increment,name varchar(80),price decimal(11,2),content text,       =>  定义primary key(id)
) engine=innodb default charset=utf8;

其他字符串类型

blob 类型:保存二进制的大型数据(字节串),没有字符集,eg:图片、音频视频等。

  • 在存储中很少将文件直接保存在数据库端,一般文件的存储都是基于路径进行操作的

enum 枚举类型:多选一,从给定的多个选项中选择一个,如gender enum(‘男’,‘女’,‘保密’)

set 集合类型:多选多,从给定的多个选项中选个多个,如hobby set(‘吃饭’,‘睡觉’,‘打豆豆’)

binary 类型和 varbinary 类型:类似charvarchar;保存字节字符串,而不是字符字符串,这意味着它们没有字符集(即保存的字符与存储的编码格式有关)

日期时间 类型

时间类型的选择比较简单,主要看你需要的时间格式,是年月日、小时分钟秒等等

date 类型(年-月-日):

  • date 类型用于具有日期部分但没有时间部分的值。 MySQL 以’YYYY-MM-DD‘格式检索和显示日期值。 支持的范围是’1000-01-01’到’9999-12-31’。

datetime 类型(年月日小时分钟秒):

  • datetime 类型用于同时包含日期和时间部分的值。 MySQL 以’YYYY-MM-DD HH:MM:SS‘格式检索和显示datetime 值。 支持的范围是’1000-01-01 00:00:00’到’9999-12-31 23:59:59’。

datetime范围相对于timestamp范围更广,‘1000-01-01 00:00:00’ to ‘9999-12-31 23:59:59’

timestamp 类型(年月日小时分钟秒):

  • timestamp 数据类型用于同时包含日期和时间部分的值。 timestamp 的范围是 ‘1970-01-01 00:00:01’ UTC 到 ‘2038-01-19 03:14:07’ UTC。

timestamp选项如果不插入时间,则MySQL会自动调用系统时间写入数据

注意:

  • 无效的 date、datetime 或 timestamp 值将转换为适当类型的’零’值(‘0000-00-00’或’0000-00-00 00:00:00’)。

time 类型(小时:分钟:秒):

  • MySQL 以 ‘HH:MM:SS’ 格式(或’HHH:MM:SS‘格式用于大小时值)检索和显示 TIME 值。TIME 值范围从’-838:59:59’到’838:59:59’。

说明:

  • 小时部分可以是这么大,因为可以使用time类型不仅代表一个时间(必须小于24小时),而且可以表示运行时间或两个事件之间的时间间隔(可能大于24小时,甚至负数)。

注意:

  • time这一列如果存储缩写,需要注意mysql的解释方式。无效的时间值会被转换成’00:00:00’
    11:12’ 表示 ‘11:12:00’,而不是’00:11:12’。

    '12'12 被解释为’00:00:12’。

year 类型 (年):

  • year(4)year(2) 的显示格式不同,但具有相同的值范围。
  • year(4) 格式,MySQL 以 YYYY 格式显示 year 值,范围为 1901 到 2155 或 0000
  • year(2)格式,MySQL 仅显示最后两位(最低有效)数字; 例如,70(1970 或 2070)或 69(2069)

无效的值将会被转换成’0000’.

SQL查询五子句

基本语法:

  • 注意:五子句的顺序是固定的,不能颠倒,否则会报错
# mysql> select */字段列表 from 数据表名称 where 子句 group by 子句 having 子句 order by 子句 limit 子句;

WHERE 条件子句

符号 说明
% 匹配0个或任意多个字符
_(下划线) 匹配单个字符
like 模糊匹配
= 等于,精确匹配
> 大于
< 小于
>= 大于等于
<= 小于等于
!=和<> 不等于
! 和 not 逻辑非
|| 和 or 逻辑或
&& 和 and 逻辑与
between…and… 两者之间
in (…) 在…
not in (…) 不在

准备测试数据:

创建数据表:
mysql> create table tb_student(id mediumint not null auto_increment,name varchar(20),age tinyint unsigned default 0,gender enum('男','女'),address varchar(255),primary key(id)
) engine=innodb default charset=utf8;插入测试数据
mysql> insert into tb_student values (null,'刘备',33,'男','湖北省武汉市');
mysql> insert into tb_student values (null,'貂蝉',18,'女','湖南省长沙市');
mysql> insert into tb_student values (null,'关羽',32,'男','湖北省荆州市');
mysql> insert into tb_student values (null,'大乔',20,'女','河南省漯河市');
mysql> insert into tb_student values (null,'赵云',25,'男','河北省石家庄市');
mysql> insert into tb_student values (null,'小乔',18,'女','湖北省荆州市');mysql> insert into tb_student values (null,'赵天云',38,'男','安徽省亳州市'),(null,'刘大备',25,'女','河南省南阳市'),(null,'关沛羽',32,'男','湖北省荆州市'),(null,'大小乔',20,'女','河南省漯河市'),(null,'貂媚蝉',25,'男','河北省石家庄市'),(null,'小大乔',18,'女','湖北省荆州市');

like模糊查询:

  • 用于数据检索,搜索关键词
命令格式:# select * from 数据表名称 where 字段名称 like '[%]字符[%]'# select * from tb_student where name like '关%';             =>  '关%'+----+-----------+------+--------+--------------------+| id | name      | age  | gender | address            |+----+-----------+------+--------+--------------------+|  3 | 关羽      |   32 | 男     | 湖北省荆州市       ||  9 | 关沛羽    |   32 | 男     | 湖北省荆州市       |+----+-----------+------+--------+--------------------+# select * from tb_student where name like '关羽%';              =>  '关羽%'+----+--------+------+--------+--------------------+| id | name   | age  | gender | address            |+----+--------+------+--------+--------------------+|  3 | 关羽   |   32 | 男     | 湖北省荆州市       |+----+--------+------+--------+--------------------+# select * from tb_student where name like '关_';              =>  '关_'+----+--------+------+--------+--------------------+| id | name   | age  | gender | address            |+----+--------+------+--------+--------------------+|  3 | 关羽   |   32 | 男     | 湖北省荆州市       |+----+--------+------+--------+--------------------+# select * from tb_student where name like '_羽';               =>  '_羽'+----+--------+------+--------+--------------------+| id | name   | age  | gender | address            |+----+--------+------+--------+--------------------+|  3 | 关羽   |   32 | 男     | 湖北省荆州市       |+----+--------+------+--------+--------------------+# select * from tb_student where name like '_羽_';              =>  '_羽_'Empty set (0.00 sec)

运算符查询:

命令格式:# select * from 数据表名称 where 字段名称{运算符}条件# select * from tb_student where age>=32;+----+-----------+------+--------+--------------------+| id | name      | age  | gender | address            |+----+-----------+------+--------+--------------------+|  1 | 刘备      |   33 | 男     | 湖北省武汉市       ||  3 | 关羽      |   32 | 男     | 湖北省荆州市       ||  7 | 赵天云    |   38 | 男     | 安徽省亳州市       ||  9 | 关沛羽    |   32 | 男     | 湖北省荆州市       |+----+-----------+------+--------+--------------------+# select * from tb_student where gender<>'男';+----+-----------+------+--------+--------------------+| id | name      | age  | gender | address            |+----+-----------+------+--------+--------------------+|  2 | 貂蝉      |   18 | 女     | 湖南省长沙市       ||  4 | 大乔      |   20 | 女     | 河南省漯河市       ||  6 | 小乔      |   18 | 女     | 湖北省荆州市       ||  8 | 刘大备    |   25 | 女     | 河南省南阳市       || 10 | 大小乔    |   20 | 女     | 河南省漯河市       || 12 | 小大乔    |   18 | 女     | 湖北省荆州市       |+----+-----------+------+--------+--------------------+

逻辑运算符查询:

命令格式:# select * from 数据表名称 where 条件 {逻辑运算符} 条件 [逻辑运算符] [条件]...# select * from tb_student where age>30 && gender!='女';       =>  逻辑与+----+-----------+------+--------+--------------------+| id | name      | age  | gender | address            |+----+-----------+------+--------+--------------------+|  1 | 刘备      |   33 | 男     | 湖北省武汉市       ||  3 | 关羽      |   32 | 男     | 湖北省荆州市       ||  7 | 赵天云    |   38 | 男     | 安徽省亳州市       ||  9 | 关沛羽    |   32 | 男     | 湖北省荆州市       |+----+-----------+------+--------+--------------------+# select * from tb_student where id=1 or id=3 or id=5;                =>  逻辑或+----+--------+------+--------+-----------------------+| id | name   | age  | gender | address               |+----+--------+------+--------+-----------------------+|  1 | 刘备   |   33 | 男     | 湖北省武汉市          ||  3 | 关羽   |   32 | 男     | 湖北省荆州市          ||  5 | 赵云   |   25 | 男     | 河北省石家庄市        |

between 区间查询:

  • 需要有一定的相关性
  • betwwed不能包含&&、||,固定语法:between...and....
  • 后一个数不能小于前一个数
命令格式:# select * from 数据表名称 where 字段 between 条件1 and 条件2 [&& 条件...]# select * from tb_student where age between 22 and 25;
=
# select * from tb_student where age>=22 and age<=25;+----+-----------+------+--------+-----------------------+| id | name      | age  | gender | address               |+----+-----------+------+--------+-----------------------+|  5 | 赵云      |   25 | 男     | 河北省石家庄市        ||  8 | 刘大备    |   25 | 女     | 河南省南阳市          || 11 | 貂媚蝉    |   25 | 男     | 河北省石家庄市        |+----+-----------+------+--------+-----------------------+# select * from tb_student where age between 22 and 25 and/&& gender<>'女';+----+-----------+------+--------+-----------------------+| id | name      | age  | gender | address               |+----+-----------+------+--------+-----------------------+|  5 | 赵云      |   25 | 男     | 河北省石家庄市        || 11 | 貂媚蝉    |   25 | 男     | 河北省石家庄市        |+----+-----------+------+--------+-----------------------+# select * from tb_student where age between 22 && 25;ERROR 1064 (42000):

in() 与 not in() 的查询:

  • 数据必须完整,不能使用%_来模糊替代
  • 括号里边使用%或_ not in()返回全部内容
  • 括号里边使用%或_ in() 会返回空
命令格式:# select * from 数据表 where 字段 [not] in (数据1,[数据2],...);# select * from tb_student where id in (2,4,6);                =>  in ()+----+--------+------+--------+--------------------+| id | name   | age  | gender | address            |+----+--------+------+--------+--------------------+|  2 | 貂蝉   |   18 | 女     | 湖南省长沙市       ||  4 | 大乔   |   20 | 女     | 河南省漯河市       ||  6 | 小乔   |   18 | 女     | 湖北省荆州市       |+----+--------+------+--------+--------------------+# select * from tb_student where address in ('湖南省长沙市');+----+--------+------+--------+--------------------+| id | name   | age  | gender | address            |+----+--------+------+--------+--------------------+|  2 | 貂蝉   |   18 | 女     | 湖南省长沙市       |+----+--------+------+--------+--------------------+# select * from tb_student where address in ('湖南省%');Empty set (0.00 sec)# select * from tb_student where gender not in ('男') && age>=20;     =>  not in ()+----+-----------+------+--------+--------------------+| id | name      | age  | gender | address            |+----+-----------+------+--------+--------------------+|  4 | 大乔      |   20 | 女     | 河南省漯河市       ||  8 | 刘大备    |   25 | 女     | 河南省南阳市       || 10 | 大小乔    |   20 | 女     | 河南省漯河市       |+----+-----------+------+--------+--------------------+

DISTINCT 数据去重子句

基本语法:

  • 作用:将字段中重复的数据去掉,然后显示出来
命令格式:# mysql > select distinct 字段1[,字段2,..] from 数据表名称;#l mysql> select age from tb_student;+------+| age  |+------+|   38 ||   25 ||   32 ||   20 ||   25 ||   18 ||   33 ||   18 ||   32 ||   20 ||   25 ||   18 |+------+# mysql> select distinct age from tb_student;      =>  distinct age,对age字段去除重复显示+------+| age  |+------+|   38 ||   25 ||   32 ||   20 ||   18 ||   33 |+------+# mysql> select distinct age,gender from tb_student;   =>  当指定多字段,需要兼顾两个字段都不重复+------+--------+| age  | gender |+------+--------+|   38 | 男     ||   25 | 女     ||   32 | 男     ||   20 | 女     ||   25 | 男     ||   18 | 女     ||   33 | 男     |+------+--------+

GROUP BY 子句

group by 子句的作用: 对某字段数据进行分组统计查询

  • 日常生活中的分组太多了,如按男女进行分组,按成绩进行分组,按院校、系部分组,按部门进行分组
  • 根据给定数据列的查询结果进行分组统计,最终得到一个分组汇总表
  • 在MySQL5.7以后版本中,分组字段必须出现在select后面的查询字段中
  • 注:一般情况下group by需与统计函数一起使用才有意义

group by 分组原理: 通过指定字段(数据列)相同数据进行分组

基本语法:

# mysql > select*from 数据表名称 group by 字段;      =>  MySQL5.7 以前# mysql > select 字段1,函数([字段2]) from 数据表名称 group by 字段1;   =>  在MySQL5.7 以后版本中,分组字段必须出现在select后面的查询字段中

统计函数:

常见统计函数 说明
max 求最大值
min 求最小值
sum 求和
avg 求平均值
count 求总行数

用法:

  • group by 字段 表示为这个字段分组
# mysql> select count(*) from tb_student;     =>  count(*)    统计数据表总记录+----------+| count(*) |+----------+|       12 |+----------+# mysql> select gender,count(*) from tb_student group by gender;   +--------+----------+| gender | count(*) |       =>  求各分组记录数+--------+----------+| 男     |        6 || 女     |        6 |+--------+----------+# mysql> select address,count(*) from tb_student group by address;+-----------------------+----------+| address               | count(*) |+-----------------------+----------+      =>  求各分组记录数| 安徽省亳州市          |        1 || 河北省石家庄市        |        2 || 河南省南阳市          |        1 || 河南省漯河市          |        2 || 湖北省武汉市          |        1 || 湖北省荆州市          |        4 || 湖南省长沙市          |        1 |+-----------------------+----------+# mysql>  select max(age) from tb_student;        =>  max(字段) 求该字段最大值+----------+| max(age) |+----------+|       38 |+----------+# mysql> select gender,max(age) from tb_student group by gender;+--------+----------+| gender | max(age) |   =>  求分组最大值+--------+----------+| 男     |       38 || 女     |       25 |+--------+----------+# mysql> select min(age) from tb_student;      =>  max(字段) 求该字段最小值+----------+| min(age) |+----------+|       18 |+----------+# mysql> select gender,min(id) from tb_student group by gender;+--------+---------+| gender | min(id) |  =>  求分组最小值+--------+---------+| 男     |       1 || 女     |       2 |+--------+---------+# mysql> select sum(age) from tb_student;      =>  sum(字段) 对字段进行求和+----------+| sum(age) |+----------+|      304 |+----------+# mysql> select gender,sum(age) from tb_student group by gender;+--------+----------+| gender | sum(age) |   =>  求分组和+--------+----------+| 男     |      185 || 女     |      119 |+--------+----------+#mysql>  select avg(age) from tb_student;        =>  avg(字段)     对字段求平均值+----------+| avg(age) |+----------+|  25.3333 |+----------+# mysql> select gender,avg(age) from tb_student group by gender;+--------+----------+| gender | avg(age) |   =>  求分组平均值+--------+----------+| 男     |  30.8333 || 女     |  19.8333 |+--------+----------+

HAVING子句

  • having与where类似,根据条件对数据进行过滤筛选, having在做简单查询时可以替代where子句

  • where针对表中的列发挥作用,查询数据

  • having针对查询结果集发挥作用,筛选数据

基本语法:

# mysql> select */字段列表 from 数据表名称 where 子句 group by 子句 having 子句

创建测试表格:

mysql> create table tb_student(id mediumint not null auto_increment,name varchar(20),age tinyint unsigned default 0,gender enum('男','女'),subject enum('ui','java','yunwei','python'),primary key(id)
) engine=innodb default charset=utf8;测试数据:
mysql> insert into tb_student values (null,'悟空',255,'男','ui'),(null,'八戒',250,'男','python'),(null,'唐僧',30,'男','yunwei'),(null,'沙僧',150,'男','java'),(null,'小白龙',100,'男','yunwei'),(null,'白骨精',28,'女','ui'),(null,'兔子精',22,'女','yunwei'),(null,'狮子精',33,'男','yunwei');

用法:

# mysql> select subject,count(*) from tb_student group by subject;+---------+----------+| subject | count(*) |     =>  对学科进行分组,统计各学科人数+---------+----------+| ui      |        2 || java    |        1 || yunwei  |        4 || python  |        1 |+---------+----------+# mysql> select subject,count(*) from tb_student group by subject having count(*)>3;+---------+----------+| subject | count(*) |       =>  对上面的结果集进一步做数据筛选+---------+----------+| yunwei  |        4 |+---------+----------+

ORDER BY子句

主要作用的就是根据某字段数据进行排序查询(升序、降序)

  • asc:升序,默认排序
  • desc:降序,需要指定

基本语法:

# select * from 数据表名称 ... order by 字段名称 asc; => 升序# select * from 数据表名称 ... order by 字段名称 desc;  =>  降序

用法:

# mysql> select * from tb_student order by age desc;+----+-----------+------+--------+---------+| id | name      | age  | gender | subject |    =>  order by    指定age 字段进行降序排序+----+-----------+------+--------+---------+|  1 | 悟空      |  255 | 男     | ui      ||  2 | 八戒      |  250 | 男     | python  ||  4 | 沙僧      |  150 | 男     | java    ||  5 | 小白龙    |  100 | 男     | yunwei  ||  8 | 狮子精    |   33 | 男     | yunwei  ||  3 | 唐僧      |   30 | 男     | yunwei  ||  6 | 白骨精    |   28 | 女     | ui      ||  7 | 兔子精    |   22 | 女     | yunwei  |+----+-----------+------+--------+---------+mysql> select * from tb_student order by age [asc];+----+-----------+------+--------+---------+| id | name      | age  | gender | subject |  =>  默认是升序排序+----+-----------+------+--------+---------+|  7 | 兔子精    |   22 | 女     | yunwei  ||  6 | 白骨精    |   28 | 女     | ui      ||  3 | 唐僧      |   30 | 男     | yunwei  ||  8 | 狮子精    |   33 | 男     | yunwei  ||  5 | 小白龙    |  100 | 男     | yunwei  ||  4 | 沙僧      |  150 | 男     | java    ||  2 | 八戒      |  250 | 男     | python  ||  1 | 悟空      |  255 | 男     | ui      |+----+-----------+------+--------+---------+

LIMIT子句

对记录的偏移量进行查询

  • limit number:查询number条记录
  • limit offset,number:从偏移量为offset开始查询,查询number条记录,offset的值从0开始(即limit子句中,数据库第一条记录的索引是0)

基本语法:

# select * from 数据表名称 ... limit number;# mysql> select * from 数据表名称 ... limit offset,number;

用法:

# mysql> select * from tb_student order by id limit 1;+----+--------+------+--------+---------+| id | name   | age  | gender | subject |    =>  limt n  提取n条记录+----+--------+------+--------+---------+|  1 | 悟空   |  255 | 男     | ui      |+----+--------+------+--------+---------+# mysql> select * from tb_student limit 0,1;+----+--------+------+--------+---------+| id | name   | age  | gender | subject |   =>  limit m,n   从第m+1行开始,查询n行记录+----+--------+------+--------+---------+  |  1 | 悟空   |  255 | 男     | ui      |+----+--------+------+--------+---------+# mysql> select * from tb_student limit 2,3;+----+-----------+------+--------+---------+| id | name      | age  | gender | subject |  =>  limit m,n   从第m+1行中查询n行记录+----+-----------+------+--------+---------+|  3 | 唐僧      |   30 | 男     | yunwei  ||  4 | 沙僧      |  150 | 男     | java    ||  5 | 小白龙    |  100 | 男     | yunwei  |+----+-----------+------+--------+---------+

SQL多表查询

两张以上的表一起查询就叫多表查询

UNION联合查询

作用: 把多个表中的数据联合在一起进行显示。

注意: union 联合查询前提是查询的表字段数要相等

应用场景: 分库分表(即如果一个数据表数据量比较大,查询时耗时比较多,我们可以将这些数据划分成多个属性一样的表格存储在不同的硬盘上,查询时联合一起查询能够加快查询速度)

创建测试表格:

表格1:
mysql> create table tb_student1(id mediumint not null auto_increment,name varchar(20),age tinyint unsigned default 0,gender enum('男','女'),subject enum('ui','java','yunwei','python'),primary key(id)
) engine=innodb default charset=utf8;测试数据:
mysql> insert into tb_student1 values (1,'悟空',255,'男','ui'),(3,'八戒',250,'男','python');表格2:
mysql> create table tb_student2(id mediumint not null auto_increment,name varchar(20),age tinyint unsigned default 0,gender enum('男','女'),subject enum('ui','java','yunwei','python'),primary key(id)
) engine=innodb default charset=utf8;测试数据:
mysql> insert into tb_student2 values (2,'唐僧',30,'男','yunwei'),(4,'八戒',20,'男','ui');备注:主键不写null原因是因为这些数据从某种意义上来说是同一个数据表的数据,所以为了不重复,写明数据的顺序,当然这个看具体需求

用法:

命令格式 :#  select*from  数据表名称1 union select*from  数据表名称2;mysql> select*from  tb_student1 union select*from  tb_student2;+----+--------+------+--------+---------+| id | name   | age  | gender | subject |+----+--------+------+--------+---------+|  1 | 悟空   |  255 | 男     | ui      ||  3 | 八戒   |  250 | 男     | python  ||  2 | 唐僧   |   30 | 男     | yunwei  ||  4 | 八戒   |   20 | 男     | ui      |+----+--------+------+--------+---------+

交叉查询

基本语法:

# mysql> select */字段列表 from 数据表1,数据表2;
或
# mysql> select */字段列表 from 数据表1 cross join 数据表2;

运行结果:

  • 字段总数 = 数据表1的字段 + 数据表2的字段

  • 总记录数 = 数据表1的记录数 * 数据表2的记录数 => (笛卡尔积)

创建测试表格:产品分类表(tb_category) 与 产品的信息表(tb_goods)

产品分类表(tb_category):

测试表格:
mysql> create table tb_category(id smallint not null auto_increment,name varchar(20),pid smallint default 0,primary key(id)
) engine=innodb default charset=utf8;测试数据:
mysql> insert into tb_category values (null,'手机',0);       =>  id=1
mysql> insert into tb_category values (null,'电脑',0);       =>  id=2
mysql> insert into tb_category values (null,'相机',0);       =>  id=3#l 备注:pid代表所属的父级类别,如果自己就是顶级分类,则为0

产品的信息表(tb_goods):

测试表格:
mysql> create table tb_goods(id int not null auto_increment,title varchar(80),price decimal(11,2),cid smallint default 0,primary key(id)
) engine=innodb default charset=utf8;测试数据:
mysql> insert into tb_goods values (null,'IPhone 11',5699.00,1);
mysql> insert into tb_goods values (null,'HP',9765.00,2);
mysql> insert into tb_goods values (null,'Nikon',9765.00,3);
mysql> insert into tb_goods values (null,'HUAWEI Mate40',4699.00,1);
mysql> insert into tb_goods values (null,'dell',9800.00,2);
mysql> insert into tb_goods values (null,'SONY',19800.00,3);#l 备注:cid代表产品的所属分类编号,与tb_category表要一一对应(与tb_category的id字段类型对应)tb_category表的id字段 和tb_goods表的cid字段 的值对应了,就说明产品信息对应这个产品分类

交叉查询演示:

  • 他就是将两个数据表的记录全部交叉查询一下

  • 交叉连接本身是没有意义的,其只是强制把两个表甚至多个表进行连接在一起。但是交叉查询中也有正确的结果,所以我们所谓的多表连接只需要在交叉连接的基础上增加一个连接条件,则就是我们想要的结果了。所以交叉查询是多表查询的基础。

# mysql> select*from tb_category;+----+--------+------+| id | name   | pid  |+----+--------+------+|  1 | 手机   |    0 ||  2 | 电脑   |    0 ||  3 | 相机   |    0 |+----+--------+------+# mysql> select*from tb_goods;+----+---------------+----------+------+| id | title         | price    | cid  |+----+---------------+----------+------+|  1 | IPhone 11     |  5699.00 |    1 ||  2 | HP            |  9765.00 |    2 ||  3 | Nikon         |  9765.00 |    3 ||  4 | HUAWEI Mate40 |  4699.00 |    1 ||  5 | dell          |  9800.00 |    2 ||  6 | SONY          | 19800.00 |    3 |+----+---------------+----------+------+# mysql> select*from tb_category cross join tb_goods;     =>  两个表交叉查询结果,+----+--------+------+----+---------------+----------+------+| id | name   | pid  | id | title         | price    | cid  | =>  查看tb_category 表id字段与tb_goods cid字段+----+--------+------+----+---------------+----------+------+ |  1 | 手机   |    0 |  1 | IPhone 11     |  5699.00 |    1 | =>  对应,属于手机分类|  2 | 电脑   |    0 |  1 | IPhone 11     |  5699.00 |    1 ||  3 | 相机   |    0 |  1 | IPhone 11     |  5699.00 |    1 ||  1 | 手机   |    0 |  2 | HP            |  9765.00 |    2 ||  2 | 电脑   |    0 |  2 | HP            |  9765.00 |    2 |    =>  对应,属于电脑分类|  3 | 相机   |    0 |  2 | HP            |  9765.00 |    2 ||  1 | 手机   |    0 |  3 | Nikon         |  9765.00 |    3 ||  2 | 电脑   |    0 |  3 | Nikon         |  9765.00 |    3 ||  3 | 相机   |    0 |  3 | Nikon         |  9765.00 |    3 |    =>  对应,属于相机分类|  1 | 手机   |    0 |  4 | HUAWEI Mate40 |  4699.00 |    1 | =>  对应,属于手机分类|  2 | 电脑   |    0 |  4 | HUAWEI Mate40 |  4699.00 |    1 ||  3 | 相机   |    0 |  4 | HUAWEI Mate40 |  4699.00 |    1 ||  1 | 手机   |    0 |  5 | dell          |  9800.00 |    2 ||  2 | 电脑   |    0 |  5 | dell          |  9800.00 |    2 |    =>  对应,属于电脑分类|  3 | 相机   |    0 |  5 | dell          |  9800.00 |    2 ||  1 | 手机   |    0 |  6 | SONY          | 19800.00 |    3 ||  2 | 电脑   |    0 |  6 | SONY          | 19800.00 |    3 ||  3 | 相机   |    0 |  6 | SONY          | 19800.00 |    3 |    =>  对应,属于相机分类+----+--------+------+----+---------------+----------+------+

内连接查询

基本语法:

# select 数据表1.字段列表,数据表2.字段列表 from 数据表1 inner join 数据表2 on 连接条件;
  • 内连接查询:把两个表甚至多个表进行连接,然后拿表1中的每一条记录与表2中的每一条记录进行匹配,如果有与之对应的结果,则显示。反之,则忽略这条记录。演示:
# mysql> select*from tb_goods inner join tb_category on tb_category.id=tb_goods.cid;+----+---------------+----------+------+----+--------+------+| id | title         | price    | cid  | id | name   | pid  |   =>  查询产品分类与产品信息所对应的字段(即 cid 和 id)+----+---------------+----------+------+----+--------+------+|  1 | IPhone 11     |  5699.00 |    1 |  1 | 手机   |    0 ||  2 | HP            |  9765.00 |    2 |  2 | 电脑   |    0 ||  3 | Nikon         |  9765.00 |    3 |  3 | 相机   |    0 ||  4 | HUAWEI Mate40 |  4699.00 |    1 |  1 | 手机   |    0 ||  5 | dell          |  9800.00 |    2 |  2 | 电脑   |    0 ||  6 | SONY          | 19800.00 |    3 |  3 | 相机   |    0 |+----+---------------+----------+------+----+--------+------+# mysql> select tb_goods.*,tb_category.name from tb_goods inner join tb_category on tb_category.id=tb_goods.cid;+----+---------------+----------+------+--------+| id | title         | price    | cid  | name   | =>  可以自定义自己想要查询的字段+----+---------------+----------+------+--------+|  1 | IPhone 11     |  5699.00 |    1 | 手机   ||  2 | HP            |  9765.00 |    2 | 电脑   ||  3 | Nikon         |  9765.00 |    3 | 相机   ||  4 | HUAWEI Mate40 |  4699.00 |    1 | 手机   ||  5 | dell          |  9800.00 |    2 | 电脑   ||  6 | SONY          | 19800.00 |    3 | 相机   |+----+---------------+----------+------+--------+

外连接查询

内连接查询要求表1和表2中的每一条记录必须要一 一对应,如果无法匹配,则这条记录会被自动被忽略掉。如果需要保留表1中的所有记录或表2中的所有记录,那么就使用外连接查询

  • 左外连接查询:把左表中的每一条数据都保留,右表匹配到结果就显示,匹配不到就NULL,右表不匹配的数据不会输出

  • 右外连接查询:把右表中的每一条数据都保留,左表匹配到结果就显示,匹配不到就NULL,左表不匹配的数据不会输出

基本语法:

左外连接查询:# select 数据表1.字段列表,数据表2.字段列表 from 数据表1 left join 数据表2 on 连接条件;右外连接查询:# select 数据表1.字段列表,数据表2.字段列表 from 数据表1 right join 数据表2 on 连接条件;

演示:

  • 给产品信息数据表增加一条鞋子信息的记录,使之与产品分类表id不对应
增加数据:# mysql > insert into tb_goods values (null,'Nike air',999.00,10);左外连接查询:# mysql > select tb_goods.*,tb_category.name from tb_goods left join tb_category on tb_goods.cid=tb_category.id;+----+---------------+----------+------+--------+| id | title         | price    | cid  | name   |    =>  左表数据保留,鞋子信息没有对应上,所以右表会显示NULL+----+---------------+----------+------+--------+|  1 | IPhone 11     |  5699.00 |    1 | 手机   ||  4 | HUAWEI Mate40 |  4699.00 |    1 | 手机   ||  2 | HP            |  9765.00 |    2 | 电脑   ||  5 | dell          |  9800.00 |    2 | 电脑   ||  3 | Nikon         |  9765.00 |    3 | 相机   ||  6 | SONY          | 19800.00 |    3 | 相机   ||  7 | Nike air      |   999.00 |   10 | NULL   |+----+---------------+----------+------+--------+右外连接查询:mysql> select tb_goods.*,tb_category.name from tb_goods right join tb_category on tb_goods.cid=tb_category.id;+------+---------------+----------+------+--------+| id   | title         | price    | cid  | name   | =>  右表数据保留,因为有匹配到,所以不会显示NULL+------+---------------+----------+------+--------+|    1 | IPhone 11     |  5699.00 |    1 | 手机   ||    2 | HP            |  9765.00 |    2 | 电脑   ||    3 | Nikon         |  9765.00 |    3 | 相机   ||    4 | HUAWEI Mate40 |  4699.00 |    1 | 手机   ||    5 | dell          |  9800.00 |    2 | 电脑   ||    6 | SONY          | 19800.00 |    3 | 相机   |+------+---------------+----------+------+--------+

别名机制:简化内外连接

通过给数据表起别名简化操作

语法分解:

原始语句:
#   mysql> select tb_goods.*,tb_category.name from tb_goods left join tb_category on tb_goods.cid=tb_category.id;拆解:第一步:查询语句# mysql> select * from tb_goods left join tb_category;第二步:起别名   g和c# mysql> select * from tb_goods g left join tb_category c;第三步:写on条件    g.cid=c.id# mysql> select * from tb_goods g left join tb_category c on g.cid=c.id;第四步:筛选需要显示的字段     g.*,c.name# mysql> select g.*,c.name from tb_goods g left join tb_category c on g.cid=c.id;修改后的字段就是第四步语句:# mysql> select g.*,c.name from tb_goods g left join tb_category c on g.cid=c.id;# mysql> select g.*,c.name from tb_goods g left join tb_category c on g.cid=c.id;+----+---------------+----------+------+--------+| id | title         | price    | cid  | name   |  =>  g.*,代表该表所有字段;c.name,代表该表的name字段+----+---------------+----------+------+--------+|  1 | IPhone 11     |  5699.00 |    1 | 手机   ||  4 | HUAWEI Mate40 |  4699.00 |    1 | 手机   ||  2 | HP            |  9765.00 |    2 | 电脑   ||  5 | dell          |  9800.00 |    2 | 电脑   ||  3 | Nikon         |  9765.00 |    3 | 相机   ||  6 | SONY          | 19800.00 |    3 | 相机   ||  7 | Nike air      |   999.00 |   10 | NULL   |+----+---------------+----------+------+--------+

MySQL语句 - sql语句相关推荐

  1. windows下bat处理执行Mysql的sql语句

    这篇文章主要介绍了windows下bat批处理执行Mysql的sql语句,需要的朋友可以参考下 有时候我们需要用bat来定时执行mysql那么就可以参考下面的代码 直接上代码: @ECHO OFF S ...

  2. shell实行mysql语句_【Mysql】shell运行mysql的sql语句_MySQL

    bitsCN.com [Mysql]shell运行mysql的sql语句 shell本身是一种脚本语言,所以不能像java一样通过api去连接数据库.shell还是要借助mysql本身的一些运行脚本才 ...

  3. PHP获取MySQL执行sql语句的查询时间

    PHP获取MySQL执行sql语句的查询时间 1. $t1=microtime(true); mysql_query($sql); echo microtime(true)-$t1; 2. //计时开 ...

  4. mysql下sql语句 update 字段=字段+字符串

    mysql下sql语句令某字段值等于原值加上一个字符串 update 表明 SET 字段= 'feifei' || 字段; (postgreSQL 用 || 来连贯字符串) MySQL连贯字符串不能利 ...

  5. mysql分析sql语句基础工具 —— explain

    转载自 https://segmentfault.com/a/1190000009724144 立即登录 [笔记] mysql分析sql语句基础工具 -- explain  mysql wateran ...

  6. Mysql中SQL语句不使用索引的情况

    Mysql中SQL语句不使用索引的情况 MySQL查询不使用索引汇总 众所周知,增加索引是提高查询速度的有效途径,但是很多时候,即使增加了索引,查询仍然不使用索引,这种情况严重影响性能,这里就简单总结 ...

  7. mysql数据库语句分类_细数MySQL中SQL语句的分类

    1:数据定义语言(DDL) 用于创建.修改.和删除数据库内的数据结构,如:1:创建和删除数据库(CREATE DATABASE || DROP  DATABASE):2:创建.修改.重命名.删除表(C ...

  8. MySQL的SQL 语句:根据从表记录个数对主表排序

    MySQL的SQL 语句:根据从表记录个数对主表排序 一个主表 news,有字段 nId(自动增长),sName.     记录:     10 name10     13 name13     20 ...

  9. php面试专题---MySQL常用SQL语句优化

    php面试专题---MySQL常用SQL语句优化 一.总结 一句话总结: 原理,万变不离其宗:其实SQL语句优化的过程中,无非就是对mysql的执行计划理解,以及B+树索引的理解,其实只要我们理解执行 ...

  10. MySQL 递归 sql语句 WITH表达式实现

    MySQL 递归 sql语句 WITH AS 实现 前言: 这里一般来说需要编一个故事但是我懒 mysql递归CTE: 8.0版本以上才有WITH AS,8.0以下版本的话请绕行----->不是 ...

最新文章

  1. SpringMVC启动后自动执行
  2. linux arch 软件管理工具 pacman 简介
  3. python常用英文单词怎么写,Python常用英文单词
  4. 1.20 main()方法
  5. 零基础带你五行代码实现聊天机器人-再这么玩?咱还能做朋友吗?
  6. ElasticSearch 知识点整理(深入)
  7. Channel Allocation HDU1373
  8. Codeforces Round #740 (Div. 2) F. Top-Notch Insertions 线段树 / 平衡树 + 组合数学
  9. bzoj3224: Tyvj 1728 普通平衡树(打个splay暖暖手)
  10. java搭建线程池框架,JAVA线程池管理及分布式HADOOP调度框架搭建
  11. P5708 【深基2.习2】三角形面积【入门题】
  12. 风变编程python笔记_自学Python和风变编程
  13. 思科CEO自爆:G20虚拟会议用的我家技术
  14. 收集最全的工业软件大集合
  15. 阿里的 P8 和 P9 到底是什么水平
  16. 2008 r2 server sql 中文版补丁_Microsoft SQL Server 2008 R2 SP1补丁 32位 官方免费版(附安装教程)...
  17. vue项目TypeScript intellisense is disabled on template.异常解决方案
  18. [JAVA][正则表达式]
  19. subprocess.Popen()的用法
  20. Unable to negotiate with xxxxport 22: no matching host key type found. Their offer: ssh-rsa,ssh-dss

热门文章

  1. 微信小程序自动化测试——自定义测试(Minium)
  2. 小程序写手机号码查吉凶,有检验手机号码正确性
  3. java跟python优势_当前Java与Python相比还有哪些优势
  4. 【敏捷开发每日一贴】敏捷实践Showcase的七宗罪
  5. java除法保留n位有效位
  6. 更优雅的字符串print——pprint库的使用
  7. [别被脱库系列]1 数据库的初恋
  8. DAX函数: calculate
  9. Java实现身份证信息比较大小
  10. IOS 7 Xcode 5 免IDP证书 真机调试 【修改自无心圆的博客】