MySQL学习0:select、连接查询、子查询、limit、CRUD

IBM公司开发的eclipse
Oracle是做数据库起家的。
Oracle收购了 MySQL AB公司。

常见的有哪些数据库管理系统呢?
Oracle MySQL DB2 Sybase “MS SqlServer支持标准sql的数据库管理系统”

登陆mysql
mysql -uroot -p密码

如果我不希望别人看到密码:
mysql -uroot -p回车
然后输入密码

MySQL端口号是3306(默认)

怎么卸载能卸载干净?
1、双击安装包,点击下一步,然后点击remove。卸载。
2、手动删除Program Files中的MysQL目录。
3、手动删除ProgramData目录(这个目录是隐藏的)中的MysQL。

MySQL中字符串类型是varchar

sql、DB、DBMS分别是什么,他们之间的关系

DB:DataBase(数据库,数据库实际上在硬盘上以文件的形式存在)
DBMS:DataBase Management System(数据库管理系统,常见的有:MySQL Oracle DB2 Sybase SqlServer...)
SQL:结构化查询语言,是一门标准通用的语言。标准的sql适合于所有的数据库产品。

SQL属于高级语言。只要能看动英语单词的,写出来的sql语句,可以读懂什么意思。

SQL语句在执行的时候,实际上内部也会先进行编译,然后再执行sql。(sql语句的编译由DBMS完成。)

DBMS负责执行sql语句,通过sql语句来操作DB当中的数据。
DBMS -(执行)-> SQL -(操作)-> DB

什么是表

表:table
表table是数据库的基本组成单元,所有的数据都以表格的形式组织,目的是可读性强。

一个表包括行和列:
行:被称为数据/记录(data)
列:被称为字段(column)

每个字段应该包括哪些属性?
字段名、数据类型、相关的约束。

对SQL语句的分类

学习MySQL主要还是学习通用的SQL语句,那么SQL语句包括增删改查,SQL语句怎么分类呢?
DQL(数据查询语言): 查询语句,凡是select语句都是DQL。
DML(数据操作语言): insert delete update,对表当中的数据进行增删改。
DDL(数据定义语言): create drop alter,对表结构的增删改。
TCL(事务控制语言): commit提交事务,rollback回滚事务。(TCL中的T是Transaction)
DCL(数据控制语言): grant授权、revoke撤销权限等。

导入数据

第一步:登录mysql数据库管理系统
dos命令窗口:
mysql -uroot -p密码

第二步:查看有哪些数据库
show databases;(这个不是SQL语句,属于MySQL的命令)
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+

第三步:创建属于我们自己的数据库
create database bjpowernode(库名);(这个不是SQL语句,属于MySQL的命令)

第四步:使用bjpowernode(库名)数据
use bjpowernode(库名);(这个不是SQL语句,属于MySQL的命令)

第五步:查看当前使用的数据库中有哪些表?
show tables;(这个不是SQL语句,属于MySQL的命令)

第六步:初始化数据
source 文件路径(也可以直接把文件拖过来)(这是一个sql文件)

对SQL脚本的理解

文件以sql结尾,这样的文件被称为“sql脚本”。

什么是sql脚本呢?
当一个文件的扩展名是.sql,并且该文件中编写的大量的sql语句,我们称这样的文件为sql脚本。

注意:直接使用source命令可以执行sql脚本。
sql脚本中的数据量太大的时候,无法打开,请使用source命令完成初始化。

删除数据库:
drop database bjpowernode(库名);

查看表结构:
desc 表名;

表中的数据:
select * from 表名;

MySQL常用命令

创建数据库:
create database 数据库名称;

查询当前使用的数据库:
select database();

查看数据库版本:
select version();

终止一条语句(结束一条语句):
\c

退出mysql:
\q或quit或exit

查看创建表的语句

show create table 表名;

简单的查询语句(DQL)

语法格式:
select 字段名1,字段名2,字段名3,...... from 表名;

提示:
1.任何一条sql语句以“;”结尾。
2.sql语句不区分大小写。

字段可以参与数学运算。

emp表.png

例如,我emp表中有月薪sal,我想查年薪
select sal * 12 from emp;

给查询结果的列重命名
select sal * 12 as yearsal from emp;

别名中有中文怎么办?
select sal * 12 as '年薪' from emp;

注意:在数据库中写字符串的时候建议使用单引号,不要使用双引号,因为有些其它数据库中不支持双引号的字符串。

注意:标准sql语句中要求字符串使用单引号括起来。虽然mysql支持双引号,尽量别用。

as关键字可以省略
select sal * 12 yearsal from emp;

查询所有字段
select * from emp;
开发中不建议这么写,影响效率。在实际开发中不建议使用*,效率较低。

条件查询

语法格式:
select
字段,字段.....
from
表名
where
条件;

执行顺序:先from,然后where,最后select

运算符

= 等于

大于
< 小于
= 大于等于
<= 小于等于
<>或!= 不等于(这俩都行)
between...and... 两个值之间,等同于>= and <=
between ...and... 是闭区间
一定是左边是小数字,右边是大数字
between and 在使用的时候必须是左小右大
between and 除了可以使用在数字方面之外,还可以使用在字符串方面(左闭右开)。

在数据库当中,NULL不是一个值,代表什么也没有,为空。
空不是一个值,不能用等号衡量。
必须使用 is null 或者 is not null

and 并且
or 或者

and的优先级高于or

注意:当运算符的优先级不确定的时候加小括号。

in 等同于or

in后面的值,不是区间,是具体的值。

not in 不在这几个值当中

like 模糊查询,支持%或下划线匹配
在模糊查询当中,必须掌握两个特殊的符号,一个是%,一个是_
%代表任意多个字符,_代表任意一个字符。

%和_都是由特殊含义,但是不排除,我们需要模糊查找时,找带有这两个字符的,所以这时候就需要 \ 转义字符了。

数据排序

order by ???;
通过某某某排序
注意:默认是升序排列

怎么指定升序或者降序呢?
asc表示升序,desc表示降序。

例子:按照工资的降序排列,当工资相同时,再按照名字的升序排列。
select ename,sal from emp order by sal desc,ename asc;

注意:多个字段,越靠前的字段越能起到主导作用,只有当前面的字段无法完成排序的时候,才会启用后面的字段。

order by后面也可以跟数字,跟的是几就表示按照第几列来排。
不建议这样使用。

执行顺序.png

分组函数

count 计数
sum 求和
avg 平均值
max 最大值
min 最小值

记住:所有的分组函数都是对“某一组”数据进行操作的。

例子.png

分组函数一共5个。分组函数还有另一个名字:多行处理函数。
多行处理函数的特点:输入多行,最终输出结果是一行。

分组函数自动忽略NULL。

什么是单行处理函数?
输入一行,输出一行。

重点:所有数据库都是这样规定的,只要有NULL参与的运算结果一定是NULL。

ifnull()空处理函数
ifnull(可能为NULL的数据,被当做什么处理) 属于单行处理函数。

SQL语当中有一个语法规则,分组函数不可以直接使用在where子句当中。
因为group by 是在where执行之后才会执行的。
(不用迷茫,你没错过,group by 在下面写着呢,往下看!!)

count所有和count某个字段的区别:
count(*):不是统计某个字段中数据的个数,二十统计总记录条数。(和某个字段无关)
count(某个字段):表示统计某个字段中不为NULL的数据总数量。

分组函数也能组合起来用:
select count(*),sun(sal),avg(sal),max(sal),min(sal) from emp;

fgroup by 和 having

group by :按照某个字段或者某些字段进行分组。
having : having是对分组之后的数据进行再次过滤。

案例:找出每一个工作岗位的最高薪资。
select max(sal) from group by job;

注意:分组函数一般都会和group by 一起使用,这也是为什么它被称为分组函数的原因。
并且任何一个分组函数(count sum avg max min )都是再group by 语句执行结束之后才会执行的。
当一条sql语句没有group by的话,整张表的数据会自成一组。

执行顺序.png

记住一个规则:当一条语句中有group by 的话,select后面只能跟分组函数和参与分组的字段。

多个字段能不能联合起来一块分组呢?
案例:找出每个部门不同工作岗位的最高薪资。
select deptno,job,max(sal) from emp group by deptno,job;

案例:找出每个部门的最高薪资,要求薪资大于2900的数据。
第一步:找出每个部门的最高薪资
select max(sal),deptno from emp group by deptno;
第二步:找出薪资大于2900
max(sal),depton from emp group by deptno having max(sal) > 2900;//这种方式效率很低
select max(sal),deptno from emp where sal > 2900 group by deptno;//这种方式效率较高,建议能够使用where过滤的尽量使用where。

案例:找出每个部门平均薪资,要求薪资大于2000的数据。
第一步:找出每个部门的平均薪资
select deptno,avg(sal) from emp group by deptno;
第二步:要求薪资大于2000的数据
select deptno,avg(sal) from emp group by deptno having avg(sal) > 2000;

那有人就要问了:为什么上边能用where,这就不能用呢?
where后面不能使用分组函数,所以这种情况只能使用having过滤。

总结一个完整的DQL语句怎么写

书写顺序不能变!!!

顺序.png

通过from查询表,
经过where条件过滤筛选,筛选出有价值的数据之后,
再进行group by分组,分完组之后,
再having进行筛选,筛选出有价值的数据,
然后我们把它select查出来,
最后order by排序输出。

关于查询结果集的去重

在需要查询的字段前加一个distinct关键字
例如:select distinct job from emp;

注意:distinct只能出现在所有字段的最前面。distinct出现在最前面表示后面的字段联合起来去重

连接查询

什么是连接查询?
在实际开发中,大部分的情况下都不是从单表中查询数据,一般都是多张表联合查询取出最终的结果。
在实际开发中,一般一个业务都会对应多张表,
比如:学生和班级,起码两张表。
学生和班级信息存储到一张表中,数据会存在大量的重复,导致数据的冗余。

连接查询怎么分类

根据语法出现的年代来划分的话,包括:
SQL92(一些老的DBA科恩那个还在使用这种语法。DBA:DataBase Administrator,数据库管理员)
SQL99(比较新的语法)

根据表的连接方式来划分,包括:
内连接:
等值连接
非等值连接
自连接
外连接:
左外连接(左连接)
右外连接(右连接)
全连接(很少用)

笛卡尔积现象

在表的连接查询方面有一种现象被称为:笛卡尔积现象。(笛卡尔乘积现象)

案例:找出每一个员工的部门名称,要求显示员工名和部门名。

dept表.png

笛卡尔积现象:如果两张表连接的话,没有任何条件限制,最终的查询结果条数是两张表中的记录条数的乘积。

select ename,dname from emp,dept;

关于表的别名:
select e.ename,d.dname from emp e,dept d;
表的别名有什么好处?
第一:执行效率高。
第二:可读性好。

怎么避免笛卡尔积现象呢?当然是加条件进行过滤。
避免了笛卡尔积现象,会减少记录的匹配次数么?
不会,次数不变,只不过显示的是有效记录。

案例:找出每一个员工的部门名称,要求显示员工名和部门名。
select e.ename,d.dname from emp e,dept d where e.deptno = d.deptno;//SQL92语法,以后不用

内连接之等值连接

最大的特点是:条件是等量关系。

案例:找出每一个员工的部门名称,要求显示员工名和部门名
SQL92(太老了,不用):
select
e.ename,d.dname
from
emp e,dept d
where
e.deptno = d.deptno;
SQL99(常用的):
select
e.ename,d.dname
from
emp e
inner join
dept d
on
e.deptno = d.deptno;

语法:
...
A
inner join
B
on
连接条件
where
...

inner可以省略的,带着inner目的是可读性好一些。

SQL99语法结构更清晰一些,表的连接条件和后来的where条件分离了。

内连接之非等值连接

最大的特点是:连接条件中的关系是非等量关系。

案例:找出每个员工的工资等级,要求显示员工名、工资、工资等级。

salgrade表.png

select
e.ename,e.sal,s.grade
from
emp e
inner join
salgrade s
on
e.salbetween s.losal and s.hisal

自连接

最大的特点是:一张表看做两张表。自己连接自己

案例:找出每个员工的上级领导,要求显示员工名和对应的领导名。
select
a.ename as '员工名',b.ename as '领导名'
from
emp a
inner join
emp b
on
a.mgr = b.empno

外连接

什么是外连接,和内连接有什么区别?
内连接:
假设A表和B表进行连接,使用内连接的话,凡是A表和B表能够匹配上的记录查询出来,这就是内连接。
AB两张表没有主副之分,两张表是平等的。

外连接:
假设A表和B表进行连接,使用外连接的话,AB两张表有一张表是主表,一张表是副表,主要查询主表中的数据,捎带着查询副表。当副表中的数据没有和主表中的数据匹配上,副表自动模拟出NULL与之匹配。

外连接的分类:
左外连接(左连接):表示左边的这张表是主表。
右外连接(右连接):表示右边的这张表是主表。

左连接有右连接的写法,右连接也会有对应的左连接的写法

案例:找出每个员工的上级领导
左连接:
select
a.ename as '员工名',b.ename as '领导名'
from
emp a
left outer join
emp b
on
a.mgr = b.empno

右连接:
select
a.ename as '员工名',b.ename as '领导名'
from
emp b
right outer join
emp a
on
a.mgr = b.empno

outer是可以省略。

在以后的实际开发中,外连接使用居多。

3张以上表怎么连接查询

...
A
join
B
join
C
on
...

表示:A表和B表先进行表连接,连接之后A表继续和C表进行连接。

案例:找出每一个员工的部门名称以及工资等级。
select
e.ename,d.dname,s.grade
from
emp e
join
dept d
on
e.deptno = d.deptno
join
salgrade s
on
e.sal between s.losal and s.hisal;

e表先和d表连接,连接条件是e.deptno = d.deptno,然后e表和s表连接,条件是 e.sal between s.losal and s.hisal;

案例.png

子查询

什么是子查询?子查询都可以出现在哪里?
select语句当中嵌套select语句,被秦韬的select语句是子查询。

子查询可以出现在哪里?

i在这几个位置.png

where子句中使用子查询

案例:找出高于平均薪资的员工信息。
第一步:找出平均薪资
select avg(sal) from emp;
得到一个平均值
第二步:where过滤
select * from emp where sal > 那个值;

第一步和第二步合并:
select * from emp where sal > (select avg(sal) from emp);

from后面嵌套子查询

案例:找出每个部门平均薪水的薪资等级。
第一步:找出每个部门平均薪水(按照部门编号分组,求sal的平均值)
select deptno,avg(sal) from emp group by deptno;
第二步:将以上的查询结果当作临时表t,让t表和salgrade s表连接,条件是:t.avgsal between s.losal and s.hisal
select t.*,s.grade from (select deptno,avg(sal) from emp group by deptno) t join s on t.avgsal between s.losal and s.hisal;

案例:找出每个部门平均的薪水等级
第一步:找出每个员工的薪水等级。
select e.ename,e.sal,e.deptnno,s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal;
第二步:基于以上结果,继续按照deptno分组,求grade平均值。
select e.deptno,avg(s.grade) from emp e join salgrade s on e.sal between s.losal and s.hisal group by e.deptno;

在select后面嵌套子查询

案例:找出每个员工所在的部门名称,要求显示员工名和部门名。

sql语句.png

union(可以将查询结果集相加)

案例:找出工作岗位是SALESMAN和MANAGER的员工

第一种:select ename,job from emp where job = 'MANAGER' or job = 'SALESMAN';

第二种:select ename,job from emp where job in( 'MANAGER' , 'SALESMAN');

第三种:
select ename,job from emp where job = 'MANAGER'
union
select ename,job from emp where job = 'SALESMAN';

两张不相干的表中的数据拼接在一起显示,就得使用union了。

union在用的时候有一个特点,就是你第一个查询结果的这个列的数量,必须跟第二个查询结果的这个列的数量一致。

limit(重点中的重点)

以后分页查询全靠它。

limit是MySQL特有的,其他数据库没有,不通用。(Oracle中有一个相同的机制,叫做rownum)

limit取结果集中的部分数据,这是它的作用。

语法机制:
limit startIndex,length
startIndex 表示起始位置
length 表示取几个

案例:取出工资前五名的员工(思路:降序取前五个)
排序:
select ename,sal from emp order by sal desc;
取前五个:
select ename,sal from emp order by sal desc limit 0,5;
select ename,sal from emp order by sal desc limit 5;

limit是sql语句最后执行的一个环节:

执行顺序.png

案例:找出工资排名在第4到第9名的员工
select ename,sal from emp order by sal desc limit 3,6;

每页显示pageSize条记录:
第pageNo页:(pageNo - 1),pageSize

pageSize:每页显示多少条记录
pageNo:显示第几页

表的创建

建表语句的语法格式:
create table 表名(
字段名1 数据类型,
字段名2 数据类型,
字段名3 数据类型,
......
);

关于MySQL当中字段的数据类型:(以下只说常见的)
int 整数型(java中的int)
bigint 长整型(java中的long)
float 浮点型(java中的float double)
char 定长字符串(String)
varchar 不定长字符串/可变长字符串(StringBuffer/StringBuilder)
date 日期类型(对应Java中java.sql.Date类型)
BLOB 二进制大对象(存储图片、视频等流媒体信息)Binary Large OBject (对应java中的Object)
CLOB 字符大对象(存储较大文本,比如,可以存储4G的字符串)Character Large OBject (对应java中的Object)
......

char和varchar怎么选择?
在实际的开发中,当某个字段中的数据长度不发生改变的时候,是定长的,例如:性别、生日等都是采用char。
当一个字段的数据长度不确定,例如:简介、姓名等都是采用varchar。

表名在数据库当中一般建议以:t_或者tbl_开始。

向表中插入数据

语法格式:
insert into 表名(字段名1,字段名2,字段名3,......) values (值1,值2,值3,......);
要求:字段的数量和值的数量相同,并且数据类型要对应相同。

可以颠倒顺序写
可以只写几个,只写几个字段的意思是,只给这几个字段赋值,其他为NULL

删除表:
drop table if exists 表名;

注意:当一条insert语句执行成功之后,表格中必然会多一行记录。即使多的这一行记录当中某些字段是NUL,后期也没有办法执行insert语句插入数据了,只能使用update进行更新。

字段可以省略不写,但是后面的value对数量和顺序都有要求。

一次插入多行数据
insert into 表名(字段名1,字段名2,字段名3,......) values (值1,值2,值3,......),(值1,值2,值3,......);

表的复制及批量插入
create table 表名 as select语句;
将查询结果当作表创建出来。

同样可以把查询结果插入到一张表中。

修改数据:update

语法格式:
update 表名 set 字段名1=值1,字段名2=值2...... where 条件;

注意:没有条件整张表数据全部更新。
注意:中间用逗号隔开。

删除数据

语法格式:
delete from 表名 where 条件;

注意:没有条件全部删除。

怎么删除大表中的数据(重点)?
truncate table 表名;//表被截断,不可回滚。永久丢失。

这个删完,数据就恢复不了了。给客户删数据,一定要再三确认。

对于表结构的修改,使用工具完成即可,因为在实际开发中表一旦设计好之后,对表结构的修改是很少的,修改表结构就是对之前的设计进行了否定,即使需要修改表结构,我们也可以直接用用工具操作。修改表结构的语句不会出现在java代码当中。出现在Java代码当中的sql包括:insert delete update select(这些都是对表中的数据操作。)

增删改查有一个术语:CRUD操作
Create(增) Retrieve(检索) Update(修改) Delete(删除)

你可能感兴趣的:(MySQL学习0:select、连接查询、子查询、limit、CRUD)