MySQL中SQL语句基本使用:从DDL到DCL的全面指南

目录

引言

一、SQL

1.1 SQL简介

1.2 通用语法

1.3 SQL分类

二、DDL(数据定义语言)

2.1 数据库的操作

2.1.1 查询库

2.1.2 使用库

2.1.3 创建库

2.1.4 删除库

2.2 表的操作

2.2.1 创建表

2.2.2 查询表

2.2.3 修改表

2.2.4 删除表

三、DML(数据操纵语言)

3.1 表中添加数据(INSERT)

3.2 修改表中数据(UPDATE)

3.3 删除表中数据(DELETE)

四、DQL(数据查询语言)

4.1 基本查询表

4.2 条件查询(where)

4.3聚合与分组查询(group by)

4.3.1 聚合函数

4.3.2 分组查询

 4.3.3 where与having区别

4.4 排序查询(order by)

4.5 分页查询(limit)

4.6 多表查询

内连接

外连接

子查询

五、DCL(数据控制语言)

六、总结

七、参考资料


引言

在数据驱动的今天,SQL(Structured Query Language)作为数据库管理和操作的标准语言,其重要性不言而喻。无论是数据分析师、数据库管理员还是软件开发人员,掌握SQL都是必备的技能之一。本博客旨在为你提供一个全面而深入的SQL语句使用指南,从基础的数据定义(DDL)、数据操纵(DML)、数据查询(DQL)到数据控制(DCL),将一一解析这些关键领域,帮助你更好地理解和应用SQL。

一、SQL

1.1 SQL简介

SQL: 一门操作关系型数据库的编程语言,定义操作所有关系型数据库的统一标准。

1.2 通用语法

SQL语句可以单行或多行书写,以分号结尾。

show databases; #查看数据库

show
databases; #查看数据库

SQL语句可以使用空格/缩进来增强语句的可读性。

show  databases; #查看数据库

MySQL数据库的SQL语句不区分大小写。

SHOW    DATABASES; #查看数据库

注释:又分为单行注释,多行注释

单行注释:-- 注释内容 或 # 注释内容(MySQL特有)

#  show databases;
-- show databases;

多行注释: /* 注释内容 */

/* show databases;*/

1.3 SQL分类

SQL语句通常被分为四大类

DDL :  数据定义语言,用来定义数据对象(数据库,表,字段)

DML:数据操作语言,用来对数据库中的数据进行增删改

DQL:数据查询语言,用来查询数据中表的记录 (业务中频繁用的是最多的了)

DCL:数据控制语言,用来创建数据库用户、控制数据库的访问权限

二、DDL(数据定义语言)

2.1 数据库的操作

2.1.1 查询库

 查询所有数据库:

show databases; # 查询所有数据库

 查询当前数据库:

select database(); # 查看当前数据库

2.1.2 使用库

使用数据库:

use  数据库名 ;

2.1.3 创建库

创建数据库:

create  database [ if  not  exists ]   数据库名 ; # 创建数据库

 :[ ] 中的 if  not  exists 为可选项 ,可加可不加 表示 如果当前创建的数据库已经存在,则不创建,否之则创建

2.1.4 删除库

删除数据库:

drop  database [ if exists ]   数据库名; #删除数据库

 注:同理 [ ]  中 的 if exists 如果有就删除,没有就不执行也不会报错。

上述语法中的database,也可以替换schema。如:

show schemas ;  #查看所有数据库

2.2 表的操作

2.2.1 创建表

create table  表名(
	字段1  字段类型  [ 约束 ]  [ comment  字段1注释 ] ,
	......
	字段n  字段类型  [ 约束 ]  [ comment  字段n注释 ] 
) [ comment  表注释 ] ;

-- 列:简单创建一个用户表
create table people(
    id int primary key auto_increment comment 'id',
    username varchar(10) not null unique comment '用户名',
    name varchar(10) not null  comment '姓名',
    sex tinyint unsigned default 1 comment '性别 1男 2女'
) comment '用户表';

 字段类型:包括数值,字符串,日期时间类型

这里就简单列举一些常用的:需要详细版的可自行提前:MySQL数据类型详细版

数值:tinyint(小整数值 占1个byte)int(大整数值 占4个byte)  bigint(极大整数值 占8个byte)   字符串: 定长字符串  char ,变长字符串 varchar ,二者区别如char(10): 最多只能存10个字符,不足10个字符,占用10个字符空间,varchar(10): 最多只能存10个字符,不足10个字符, 按照实际长度存储 因此char 性能高 但是浪费空间 varchar 性能低 节省空间 因为要逻辑判断一下。日期时间类型 :date 只包括年月日 (比如存储我们的生日) 格式:YYYY-MM-DD  ,datetime 混合日期和时间值:(我们业务中的更新时间字段类型) 格式:YYYY-MM-DD HH:MM:SS

约束:约束是作用于表中字段上的规则,用于限制存储在表中的数据。目的:保证数据库中数据的正确性、有效性和完整性。常见约束如下:

not  null :非空约束:限制该字段值不能为null

unique: 唯一约束: 保证字段的所有数据都是唯一、不重复的

primary:key 主键约束: 主键是一行数据的唯一标识,要求非空且唯一

default: 默认约束 保存数据时,如果未指定该字段值,则采用默认值

foreign  key :外键约束 让两张表的数据建立连接,保证数据的一致性和完整性 当然我们一般也都不这样用,一般多表建联都是通过逻辑外键,不用物理外键,下面简单介绍一下

外键约束 :

物理外键:概念:使用 foreign key 定义外键关联另外一张表。 缺点: 影响增、删、改的效率(需要检查外键关系)。 仅用于单节点数据库,不适用与分布式、集群场景。 容易引发数据库的死锁问题,消耗性能

逻辑外键: 概念:在业务层逻辑中,解决外键关联。 通过逻辑外键,就可以很方便的解决上述问题。

 2.2.2 查询表

查询当前数据库所有表:

show tables;#查看当前数据库下所有表

查询表结构:

desc  表名;

 查询建表语句:

show create table 表名; #查看表结构

 2.2.3 修改表

表中添加字段 

alter table 表名  add  字段名  类型(长度)  [comment  注释]  [约束];

修改表中字段类型

alter table 表名 modify  字段名  新数据类型(长度);

修改表中字段名和字段类型

alter table 表名 change  旧字段名  新字段名  类型 (长度)  [comment 注释]  [约束];

删除字段

alter table 表名 drop  column 字段名;

 修改表名

rename table 表名 to  新表名;

2.2.4 删除表

rename table 表名 to  新表名; #修改表名

三、DML(数据操纵语言)

3.1 表中添加数据(INSERT)

指定字段添加数据:

insert into 表名 (字段名1, 字段名2)  values (值1, 值2);

-- 列
insert into people(username,name) values('zhangsan','张三'); #插入数据

全部字段添加数据:

insert into 表名 values (值1, 值2, ...); # 表名后不指定字段,则默认就是全表,所有字段都得赋值等效
如下
-- 简单创建一个用户表
create table people(
    id int primary key auto_increment comment 'id',
    username varchar(10) not null unique comment '用户名',
    name varchar(10) not null  comment '姓名',
    sex tinyint unsigned default 1 comment '性别 1男 2女'
) comment '用户表';

-- People中插入第1条数据
insert into people(id, username, name, sex) VALUES (null, 'zhangsan', '唱跳', 1);
-- People中插入第2条数据
insert into people VALUES (null, 'zhangsan', 'rap蓝球', 1);

 下面就不举例了,根据语法操作来就可以了。

批量添加数据(指定字段):

insert into 表名 (字段名1, 字段名2)  values (值1, 值2), (值1, 值2);

 批量添加数据(全部字段)

insert into 表名 values (值1, 值2, ...), (值1, 值2, ...);

注意事项:

  1. 插入数据时,指定的字段顺序需要与值的顺序是一一对应的。
  2. 字符串和日期型数据应该包含在引号中。
  3. 插入的数据大小,应该在字段的规定范围内。 

3.2 修改表中数据(UPDATE)

update  表名  set  字段名1 = 值1 , 字段名2 = 值2 , .... [ where  条件 ] ;

注意事项:

修改语句的条件可以有,也可以没有,如果没有条件,则会修改整张表的所有数据。 

3.3 删除表中数据(DELETE)

delete  from  表名  [ where  条件 ];

注意事项: 

  1. DELETE 语句的条件可以有,也可以没有,如果没有条件,则会删除整张表的所有数据。
  2. DELETE 语句不能删除某一个字段的值(如果要操作,可以使用UPDATE,将该字段的值置为NULL)。 

四、DQL(数据查询语言)

4.1 基本查询表

查询表中多个字段:

-- 语法

select  字段1, 字段2, 字段3  from   表名;

-- 列查询从people表中查询id字段 name字段和username字段

select id name,username from people;

查询表中所有字段(通配符):

select  *  from   表名;

 设置表中字段别名

select  字段1  [ as  别名1 ] , 字段2  [ as  别名2 ]   from   表名;

select id as 编号, name as 姓名 from people;

-- 也可以直接省略as 字段后直接写别名
select id  '编 号', name  '姓 名' from people;

注:如果别名中有空格或者特殊符合,需要加上单引号或者双引号 当然规范点,还是都加上

 去除表中某字段重复记录:

select  distinct  字段列表  from   表名;

   注意事项: 

* 号代表查询所有字段,在实际开发中尽量少用(不直观、影响效率) 

4.2 条件查询(where)

select  字段列表  from   表名   where   条件列表 ;

 构建条件得运算符有2类,一类是比较运算符另一类就是逻辑运算符

比较运算符	功能
>	        大于
>=	        大于等于
<	        小于
<=	        小于等于
=	        等于
<>  或 !=	不等于
between ... and ...	在某个范围之内(含最小、最大值)
in(...)	在in之后的列表中的值,多选一
like  占位符	模糊匹配(_匹配单个字符, %匹配任意个字符)
is null	    是null

逻辑运算符	功能
and  或  &&	并且 (多个条件同时成立)
or  或  ||	或者 (多个条件任意一个成立)
not  或  !	非 , 不是

这些都是很灵活得,根据需求通过这些来构建适合得你得语句就可以了,随便列举一点。 

-- 1. 查询 姓名为 何政 得信息
select * from people where name = '何政';
-- 2. 查询 id小于等于5的学生 信息
select * from people where id <=5;
-- 3. 查询 学生没有职位 的学生信息
select * from people where position is null;
-- 4. 查询 添加学生日期在    2029-08-05  到 2029-08-06  之间的学生信息
select * from people where  create_time between '2029-08-05' and '2029-08-06';
-- 5. 查询 添加学生日期在    2029-08-05  到 2029-08-06  之间 且性别为男 的学生信息
select * from people where  create_time between '2029-08-05' and '2029-08-06' and sex = 1;
-- 6 查询职位为班长、室长、社会实践委员的学生信息
select * from people where position='班长' or position='室长' or position='社会实践委员';

select * from people where position in ('班长','室长','社会实践委员');
-- 7 查询姓名为两个字的
select * from people where name like '__';
-- 8 查询姓名为何姓
select * from people where name like '何%'; 

4.3聚合与分组查询(group by)

分组查询一般都会伴着聚合统计进行且查询的字段一般为聚合函数分组字段,查询其他字段无任何意义。

4.3.1 聚合函数
介绍:将一列数据作为一个整体,进行纵向计算。
函数	功能
count	统计数量  (注:不对 null进行运算得)
max	    最大值
min	    最小值
avg	    平均值
sum	    求和

语法:select  聚合函数(字段列表)  from   表名 ;


-- 列如下

-- 查询总行数
select count(*) from people; # 查询总行数
select count(1) from people; # 查询总行数
select count(name) from people; # 查询总行数
-- 查询最早添加得学生
select min(create_time) from people; # 查询最早添加得学生
-- 查询最晚添加得学生
select max(create_time) from people; # 查询最早晚加得学生
-- 平均年龄
select avg(age) from people; # 平均年龄
-- 总年龄之和
select sum(age) from people; # 总年龄之和

注意事项:

  1. null值不参与所有聚合函数运算。
  2. 统计数量可以使用:count(*)   count(字段)   count(常量),推荐使用count(*)。其实我们了解过count优化都知道其实 mysql默认得InnoDB引擎执行count(*)并不会把全部字段取出来,而是专门做了优化,不会取值,服务器直接进行累加。
  3. 按照效率大致排序得话 count(*)约等于 count(1) > count(主键id) > count(字段 没有 not null 约束) 其实这里如果字段有not null 约束 的话,count(字段)和count(主键id)也差不多,可以算一样了。
4.3.2 分组查询
-- 语法

select  字段列表  from   表名  [ where   条件 ]  group   by  分组字段名  [ having  分组后过滤条件 ];


-- 列


-- 查询创建时间在‘2024-02-25’(包含)之后得员工,并且对结果按职位分组,查询出每个职位得员工数后,选取员工数量大于2得职位

-- #错误的示符 while之后不能用聚合函数
select position,count(*) from people where create_time >= '2024-02-25' and count(*)>2 group by position ;

-- 正确的示符 用having
select position,count(*) from people where create_time >= '2024-02-25' group by position having count(*)>2;

 4.3.3 where与having区别
  1. 执行时机不同:where是分组之前进行过滤,不满足where条件,不参与分组;而having是分组之后对结果进行过滤。
  2. 判断条件不同:where不能对聚合函数进行判断,而having可以。

注意事项:

  1. 分组之后,查询的字段一般为聚合函数分组字段,查询其他字段无任何意义,会报错得。
  2. 执行顺序: where  >  聚合函数 > having 。 

4.4 排序查询(order by)

条件查询:select  字段列表  from   表名   [ where   条件列表 ] [ group by  分组字段 ] order  by  字段1  排序方式1 , 字段2  排序方式2......;

示例: 

select * from people order by  create_time asc ,age desc; # asc 可以省略默认就是asc 查询所有数据,并按照创建时间升序,年龄降序

select position,count(*) from people where create_time >= '2024-02-25' group by position having count(*)>2 order by count(*) desc;

 排序方式:

ASC:升序(默认值) DESC:降序

注意事项:

如果是多字段排序,当第一个字段值相同时,才会根据第二个字段进行排序。 

4.5 分页查询(limit)

select  字段列表  from   表名  limit  起始索引, 查询记录数 ;

注意事项:

  1. 起始索引从0开始,起始索引 = (查询页码 - 1)* 每页显示记录数。
  2. 分页查询是数据库的方言,不同的数据库有不同的实现,MySQL中是LIMIT。
  3. 如果查询的是第一页数据,起始索引可以省略,直接简写为 limit 10。 

4.6 多表查询

以上我们都是查询得单表,多表查询我们也经常用到,自然也设计到多表设计,就简单插曲一下多表之间关系对应得一般设计:

一对多

案例:部门对员工

关系:一个部门下可以有多个员工,当时员工只能在一个部门上班(别说你是双修得)

解决:在多的一方添加外键,关联另外一方的主键。


 一对一

案例:用户 与 身份证信息 的关系 

关系: 一对一关系,多用于单表拆分,将一张表的基础字段放在一张表中,其他字段放在另一张表中,以提升操作效率

解决:任意一方,添加外键,关联另外一方的主键。


 多对多

案例:案例: 学生 与 课程的关系

关系: 一个学生可以选修多门课程,一门课程也可以供多个学生选择

设计表:

解决:通过中间表来维护,中间表的两个外键,分别关联另外两张表的主键

内连接

以下案例都会借助如下部门和打工人员工这2张表简单演示:只需要关注员工表是关联了部门ID就可以了

create table tb_dept
(
    id      int unsigned  primary key auto_increment comment '主键ID' ,
    name        varchar(10)  unique not null comment '部门名称',
    create_time datetime    not null comment '创建时间',
    update_time datetime    not null comment '修改时间'
  
)
    comment '部门表';

create table tb_emp
(
    id          int unsigned auto_increment comment 'ID'
        primary key,
    username    varchar(20)                  not null comment '用户名',
    password    varchar(32) default '123456' null comment '密码',
    name        varchar(10)                  not null comment '姓名',
    gender      tinyint unsigned             not null comment '性别, 说明: 1 男, 2 女',
    image       varchar(300)                 null comment '图像',
    job         tinyint unsigned             null comment '职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管, 5 咨询师',
    entrydate   date                         null comment '入职时间',
    dept_id     int unsigned                 null comment '部门ID',
    create_time datetime                     not null comment '创建时间',
    update_time datetime                     not null comment '修改时间',
    constraint username
        unique (username)
)
    comment '员工表';

隐式内连接:

select  字段列表   from   表1 , 表2   where   条件 ... ;

显式内连接:

select  字段列表   from   表1  [ inner ]  join 表2  on  连接条件 ... ;

案例: 

-- 查询员工的姓名,及所属的部门名称(隐式内连接)
select tb_emp.name,tb_dept.name from tb_dept,tb_emp where tb_dept.id = tb_emp.dept_id;
-- 起别名 表名字太长麻烦 注齐了别名后面访问字段需要通过别名访问
select e.name ‘员工姓名’,d.name ‘部门’ from tb_dept as d,tb_emp as e where d.id = e.dept_id;
-- 查询员工的姓名,及所属的部门名称(显式内连接)
select tb_emp.name,tb_dept.name from tb_emp inner join tb_dept on tb_dept.id = tb_emp.dept_id;

 :内连接是查询得是表与表之间交集得部分,如果表与表之间没有产生关联得数据是查不出来得。比如以上场景,一个员工的部门字段是NULL,就是没有关联部门,与部门没有关系,通过员工部门字段于部门主键ID来关联查询,那么这个员工数据是查不出来的。因为他们之间没有关系,如果需要查出来,就要通过外连接了。

外连接

左外连接:以左表为基准,会包含左表所有数据,当然也包含交集的部分。

select  字段列表   from   表1  left  [ outer ]  join 表2  on 连接条件 ... ;

 右外连接:以右表为基准,会包含左表所有数据,当然也包含交集的部分。其实左右不用区分太多,掌握一种就可以了,因为他们之间可以互相转化的。

select  字段列表   from   表1  right  [ outer ]  join 表2  on  连接条件 ... ;

简而言之:就是以某表为基准,会查询这个表对应字段所有的数据,然后在补充这个连接条件对应的数据,有这个数据我就补充上,没有就是NULL。 

案例:

-- 查询员工表 所有 员工姓名,和对应的部门名称 (左外连接)
select tb_emp.name,tb_dept.name from tb_emp left join tb_dept on tb_dept.id = tb_emp.dept_id;
-- 查询员工表 所有 员工姓名,和对应的部门名称 (左外连接)->(右外连接)
select tb_emp.name,tb_dept.name from tb_dept right join  tb_emp on tb_dept.id = tb_emp.dept_id;
-- 查询部门表所有 部门名称,和对应的员工姓名(右外连接)
select tb_emp.name,tb_dept.name from tb_emp right join tb_dept on tb_dept.id = tb_emp.dept_id;

子查询

  1. 介绍:SQL语句中嵌套select语句,称为嵌套查询,又称子查询。
  2. 形式:select  *  from   t1   where  column1 =  ( select  column1  from  t2  … );
  3. 子查询外部的语句可以是insert / update / delete / select 的任何一个,最常见的是 select。

分类:

标量子查询:子查询返回的结果为单个值

列子查询:子查询返回的结果为一列

行子查询:子查询返回的结果为一行

表子查询:子查询返回的结果为多行多列 


 标量子查询:子查询返回的结果是单个值(数字、字符串、日期等),最简单的形式 常用的操作符:=   <>    >     >=     <    <=      

案例:查询何政入职之后的员工信息

-- 查询何政入职之后的员工信息
-- 1 查询入职时间 2.查通过时间查找大于这个时间的员工
select * from tb_emp where entrydate > (select entrydate from tb_emp where name = '何政');

 列子查询:子查询返回的结果是一列(可以是多行) 常用的操作符:in  、not in等

案例:查询”丐帮部“ 和 ”乞丐部“的所有员工信息

-- 列子查询
-- 查询”丐帮部“ 和 ”乞丐部“的所有员工信息
-- 1.先查询出”丐帮部“ 和 ”乞丐部“的id
select id from tb_dept where name = '丐帮部' or name = '乞丐部';
-- 2.通过id查询出员工信息
select * from tb_emp where dept_id in (1,2);
-- 3.合并
select * from tb_emp where dept_id in (select id from tb_dept where name = '丐帮部' or name = '乞丐部');

  行子查询:子查询返回的结果是一行(可以是多列)。 常用的操作符:=  、<> 、in 、not  in

案例:查询与”蔡徐坤“ 的入职日期 及 部门都相同的员工信息

-- 行子查询
-- 查询与”蔡徐坤“ 的入职日期 及 部门都相同的员工信息
-- 1.先查询出”蔡徐坤“的入职日期 及部门
select entrydate,dept_id from tb_emp where name = '蔡徐坤';
-- 2.通过查询出的信息,查询出同日期及职位的员工信息
select * from tb_emp where entrydate = '2019-05-03' and dept_id = 4;
-- 其实 这里and 也可以同这样子写
select * from tb_emp where (entrydate , dept_id)=('2019-05-03',4) ;
-- 3.合并
select * from tb_emp where (entrydate , dept_id) = (select entrydate,dept_id from tb_emp where name = '蔡徐坤');

表子查询:子查询返回的结果是多行多列,常作为临时表 。常用的操作符:in 

案例:查询入职日期是‘1998-08-02’ 之后的 员工信息,及部门名称

-- 查询入职日期是‘1998-08-02’ 之后的 员工信息,及部门名称
-- 1.先查询出入职日期是‘1998-08-02’ 之后的员工信息
select * from tb_emp where entrydate > '1998-08-02';
-- 2.再通过员工信息这个临时表,查询出员工信息及部门名称
select e.* ,d.name from (select * from tb_emp where entrydate > '1998-08-02') e left join tb_dept d on e.dept_id = d.id;

五、DCL(数据控制语言)

在数据库管理系统中负责访问控制和安全性的关键作用。它允许数据库管理员定义谁可以访问数据库中的哪些数据,以及他们可以进行哪些操作。专门用于处理数据库的安全性和权限管理。这里就不介绍了,具体详见可以看看其他博客。

六、总结

SQL(结构化查询语言)是关系数据库管理系统的标准编程语言,其核心功能通过四大类别的语句实现:数据定义语言(DDL)、数据操作语言(DML)、数据查询语言(DQL)、和数据控制语言(DCL)。

SQL的这四大类别语句共同构成了其强大的数据库管理和操作能力,为数据的管理、查询、更新和安全性保障提供了全面的支持。无论是数据库管理员还是开发人员,都需要熟练掌握这些SQL语句,以高效地管理和维护数据库系统。

七、参考资料

《深入浅出MySQL:数据库开发、优化与管理维护(第3版)》《深入浅出MySQL:数据库开发、优化与管理维护(第3版)》 源自网易公司多位资深数据库专家数年的经验总结和MySQL数据库的使用心得,在之前版本的基础之上,基MySQL5.7版本进行了内容升级,同时也对MySQL 8.0的重要功能进行了介绍。除了对原有内容的更新之外,本书还新增了作者在高可用架构、数据库自动化运维,以及数据库中间件方面的实践和积累。本书分为“基础篇”、“开发篇”、“优化篇”、“管理维护篇”和“架构篇”5个部分,共32章。本书内容实用,覆盖广泛,讲解由浅入深,还提供了大量来自一线的工作实例,进一步提升了本书的实战性和可操作性。适合数据库管理人员、数据库开发人员、系统维护人员、数据库初学者及其他数据库从业人员阅读,

  • 25
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

何政@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值