数据库基础(超详细版)

时间:2024-11-12 21:43:43

目录

简介:

三大范式:

sql语句分类:

DDL操作数据库:

DML操作: 

 DCL

 DQL

模糊查询

字段控制查询 

 排序

聚合函数

 分组查询

 HAVING子句

limit关键字和分页查询


简介:

数据库(DataBase,DB):指长期保存在计算机的存储设备上,按照一定规则组织起来,可以被各种用户或应用共享的数据集合。
数据库管理系统(DataBase Management System,DBMS):指一种操作和管理数据库的大型软件,用于建立、使用和维护数据库,对数据库进行统一管理和控制,以保证数据库的安全性和完整性。
用户通过数据库管理系统访问数据库中的数据。
数据库软件应该为数据库管理系统,数据库是通过数据库管理系统创建和操作的。
数据库:存储、维护和管理数据的集合。

三大范式:

第一范式:无重复的列。当关系模式R的所有属性都不能在分解为更基本的数据单位时,称R是满足第一范式的,简记为1NF。满足第一范式是关系模式规范化的最低要求,否则,将有很多基本操作在这样的关系模式中实现不了。
第二范式:属性完全依赖于主键 [ 消除部分子函数依赖 ]。如果关系模式R满足第一范式,并且R得所有非主属性都完全依赖于R的每一个候选关键属性,称R满足第二范式,简记为2NF。第二范式(2NF)是在第一范式(1NF)的基础上建立起来的,即满足第二范式(2NF)必须先满足第一范式(1NF)。第二范式(2NF)要求数据库表中的每个实例或行必须可以被唯一地区分。为实现区分通常需要为表加上一个列,以存储各个实例的唯一标识。这个唯一属性列被称为主关键字或主键、主码。
第三范式:属性不依赖于其它非主属性 [ 消除传递依赖 ]。设R是一个满足第一范式条件的关系模式,X是R的任意属性集,如果X非传递依赖于R的任意一个候选关键字,称R满足第三范式,简记为3NF. 满足第三范式(3NF)必须先满足第二范式(2NF)。第三范式(3NF)要求一个数据库表中不包含已在其它表中已包含的非主关键字信息。(eg:第一张表是学生表,主要信息为姓名,次要信息为成绩,那么其他的表中,就不能包含成绩。)
注:关系实质上是一张二维表,其中每一行是一个元组,每一列是一个属性
第二范式(2NF)和第三范式(3NF)的概念很容易混淆,区分它们的关键点在于,2NF:非主键列是否完全依赖于主键,还是依赖于主键的一部分;3NF:非主键列是直接依赖于主键,还是直接依赖于非主键列。

sql语句分类:

- DDL(Data Definition Language):数据定义语言,用来定义数据库对象:库、表、列等。
- DML(Data Manipulation Language):数据操作语言,用来定义数据库记录(数据)增删改。
- DCL(Data Control Language):数据控制语言,用来定义访问权限和安全级别。
- DQL(Data Query Language):数据查询语言,用来查询记录(数据)查询。
注意:sql语句以;结尾
mysql中的关键字不区分大小写

DDL操作数据库:

DDL是用来增加、删除、修改数据库中的表的操作。

在cdm窗口,先找到数据库的路径:

如:我的路径:D:\mysql\mysql-8.0.28-winx64\bin

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_20,color_FFFFFF,t_70,g_se,x_16

 打开后,登录数据库:

mysql -u root -p

登录成功后:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_20,color_FFFFFF,t_70,g_se,x_16

 创建数据库的命令:

 create database 语句用于创建新的数据库

如何验证是否创建成功呢?

查看数据库:

 show databases;用来查看所有数据库

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_8,color_FFFFFF,t_70,g_se,x_16

创建成功(其余的数据库都是在安装过程中默认创建好的,不能删除!)

 修改数据库:

alter database 数据库名 character set 编码方式

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_14,color_FFFFFF,t_70,g_se,x_16

删除数据库: 

drop database 数据库名;

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_10,color_FFFFFF,t_70,g_se,x_16

再次显示所有数据库:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_12,color_FFFFFF,t_70,g_se,x_16

可以看到mydb1已经删除了。

查看当前使用的数据库 :
Select database(); 

当前未链接数据库。

那么我们来连接一个数据库: 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_7,color_FFFFFF,t_70,g_se,x_16

连接后显示当前数据库,即连接成功。

创建数据表:

CREATE TABLE 表名(
列名1 数据类型 [约束],
列名2 数据类型 [约束],
列名n 数据类型 [约束]
); 

注意:表名,列名是自定义,多列之间使用逗号间隔,最后一列的逗号不能写
[约束] 表示可有可无。

(常用数据类型:
int:整型
double:浮点型,例如double(5,2)表示最多5位,其中必须有2位小数,即最大值为
999.99;默认支持四舍五入
char:固定长度字符串类型; char(10) 'aaa ' 占10位
varchar:可变长度字符串类型; varchar(10) 'aaa' 占3位
text:字符串类型,比如小说信息;
blob:字节类型,保存文件信息(视频,音频,图片);
date:日期类型,格式为:yyyy-MM-dd;
time:时间类型,格式为:hh:mm:ss
timestamp:时间戳类型 yyyy-MM-dd hh:mm:ss 会自动赋值
datetime:日期时间类型 yyyy-MM-dd hh:mm:ss)

我们创建一个新的数据库来创建数据表:数据库yhp

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_10,color_FFFFFF,t_70,g_se,x_16

显示当前数据库:

 创建数据表:列有:name,age,sex。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_17,color_FFFFFF,t_70,g_se,x_16

查看表: show tables;

查看列信息:desc student;

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_15,color_FFFFFF,t_70,g_se,x_16

 删除表:drop table student;

 删除后再次查看即为空。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_9,color_FFFFFF,t_70,g_se,x_16

 修改数据表(刚刚删除的学生数据表已重新创建):

1、添加列:alter table 表名 add 新列名 新的数据类型 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_12,color_FFFFFF,t_70,g_se,x_16
添加成功:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_14,color_FFFFFF,t_70,g_se,x_16

2、修改列:alter table 表名 change 旧列名 新列名 新的数据类型 

将name 修改为studentname:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_18,color_FFFFFF,t_70,g_se,x_16

 3、删除列:alter table 表名 drop 列名

删除image:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_17,color_FFFFFF,t_70,g_se,x_16

4、修改表名:alter table 旧表名 rename 新表名; 

将student改为user: 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_17,color_FFFFFF,t_70,g_se,x_16

 5、查看表格的创建细节:

show create table 表名;

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_15,color_FFFFFF,t_70,g_se,x_16

可以看到创建表的语句,还有默认的引擎为utf8; 

6、修改字符集:(若已经是utf8,就最好不要随便修改)

alter table 表名 character set 编码方式。

DML操作: 

DML是对表中的数据进行增insert、删delete、改update的操作。

 还是在原始的student中演示:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_15,color_FFFFFF,t_70,g_se,x_16

1、插入操作 insert:

insert into 表名(列名) values(数据值);

eg:insert into student(stuname,stuage,stusex,birthday) values('小白',18,'a','2002-6-9');

注意:1多列和多个列值之间使用逗号隔开 

        2.列名要和列值一一对应 

        3.非数值的列值两侧需要加单引号
 在表中插入数据: 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_17,color_FFFFFF,t_70,g_se,x_16

 注意: 添加数据的时候可以将列名省略,但是!必须是当给所有列添加数据的时候才可以。
此时列值的顺序按照数据表中列的顺序执行。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_14,color_FFFFFF,t_70,g_se,x_16

 此时,表中的列顺序为name age sex。所以我们添加的顺序也必须是 name age sex

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_14,color_FFFFFF,t_70,g_se,x_16

注意:也可以同时添加多行 :

insert into 表名(列名) values(第一行数据),(第二行数据),(),();

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_20,color_FFFFFF,t_70,g_se,x_16

如图提示,4rows(即四行添加成功)

查询所有数据:select *from 表名: 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_8,color_FFFFFF,t_70,g_se,x_16

总结:列名与列值的类型、个数、顺序要一一对应。
参数值不要超出列定义的长度。
如果插入空值,请使用null
插入的日期和字符一样,都使用引号括起来。 

2、修改(更新)操作:update:

update 表名 set 列名1=列值1,列名2=列值2 ... where 列名=值 (不需要限定即全改的话就不用where)

将所有age改为22: 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_10,color_FFFFFF,t_70,g_se,x_16

 限定:限定语句也可以为多条,每条之间用逗号隔开。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_14,color_FFFFFF,t_70,g_se,x_16

改一行的多列:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_16,color_FFFFFF,t_70,g_se,x_16

 在woky的age上加10:

sql中的运算符:
(1)算术运算符:+,-,*,/(除法),求余(%)
示例:
        5/2
        5%2
        2/5
        2%5
(2)赋值运算符:=
 注:赋值方向:从右往左赋值
示例: name='张三'
(3) 逻辑运算符:
and(并且),or(或者),not(取非)
作用:用于连接多个条件时使用
(4) 关系运算符:
>,<,>=,<=,!=(不等于),=(等于),<>(不等于)

补充:

等于空:xxx = ' '或者写xxx is null;

如果一列做判断时有两个值:eg:年龄既不是19也不是20应该怎么写?

应该写成:age!=19 or age !=20.而不能写成:age!=19 or 20.这就错了!

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_16,color_FFFFFF,t_70,g_se,x_16

 3、删除:delete:可以删除全部,也可以删除某一条或某一部分。

 delete from 表名 【where 列名=值】 (where同为限定作用)

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_12,color_FFFFFF,t_70,g_se,x_16

删除表中所有信息:表中信息没了,但是表还在!

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_11,color_FFFFFF,t_70,g_se,x_16

 第二种删除:truncate table 表名;

与delete的区别: DELETE 删除表中的数据,表结构还在;删除后的数据可以找回
- TRUNCATE 删除是把表直接DROP掉,然后再创建一个同样的新表。
- 删除的数据不能找回。执行速度比DELETE快。

 DCL

dcl是用来设置或更改数据库用户或角色权限的语句。

创建用户:有三种方法:

一、create user 用户名@指定ip identified by 密码;

在此处,我们创建一个用户名为:yhpa的用户,localhost为本机ip。密码:abc

二、create user 用户名@客户端ip identified by 密码; 指定IP才能登陆

eg:create user test456@10.4.10.18 IDENTIFIED by 'test456'

三、create user 用户名@‘% ’ identified by 密码 任意IP均可登陆 (通常用于给团队其他成员授权)

eg:create user test7@'%' IDENTIFIED by 'test7' 

给用户授权:

一、给指定的用户授予指定的数据库里的所有的表的指定的权限。

grant 权限1,权限2,........,权限n on 数据库名.* to 用户名@IP;  (其中的数据库名

.*的意思就是这个数据库中的所有表)

在此处我们授予ypha用户yhp数据库的增删改查权限。 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_20,color_FFFFFF,t_70,g_se,x_16

 二、给指定的用户授予所有的数据库中的所有的表的所有权限

grant all on *.* to 用户名@IP; 

用户查询权限:show grants for 用户名@IP; 

查询yhpa的权限  

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_20,color_FFFFFF,t_70,g_se,x_16

 撤销用户权限:revoke 权限1,权限2,........,权限n on 数据库名.* from 用户名@IP; 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_20,color_FFFFFF,t_70,g_se,x_16 由此易见删除了select 查找权限 。

删除用户:drop user 用户名@IP;

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_10,color_FFFFFF,t_70,g_se,x_16

检查一下是否删除了:

先退出,再重新用yhpa登录:结果显示不存在!

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_20,color_FFFFFF,t_70,g_se,x_16

 DQL

 DQL是数据库查询语言。(重要)

 数据库执行DQL语句不会对数据进行改变,而是让数据库发送结果集给客户端。查询返回的结果是一张虚拟表。

查询关键字:SELECT
语法: SELECT 列名 FROM 表名 【WHERE --> BROUP BY-->HAVING--> ORDER BY】
* 代替列明表示所有列。

关键字 作用
SELECT   要查询的列名称
FROM   表名称
WHERE 限定条件 /*行条件*/
GROUP BY grouping_columns /*对结果分组*/
HAVING condition /*分组后的行条件*/
ORDER BY sorting_columns /*对结果分组*/
LIMIT offset_start, row_count /*结果限定*/

 此处我们创建一个学生表并添加数据:

#创建表stu
CREATE TABLE stu (
sid CHAR(6),
sname VARCHAR(50),
age INT,
gender VARCHAR(50)
);
#添加数据
INSERT INTO stu VALUES('S_1001', 'liuYi', 35, 'male');
INSERT INTO stu VALUES('S_1002', 'chenEr', 15, 'female');
INSERT INTO stu VALUES('S_1003', 'zhangSan', 95, 'male');
INSERT INTO stu VALUES('S_1004', 'liSi', 65, 'female');
INSERT INTO stu VALUES('S_1005', 'wangWu', 55, 'male');
INSERT INTO stu VALUES('S_1006', 'zhaoLiu', 75, 'female');
INSERT INTO stu VALUES('S_1007', 'sunQi', 25, 'male');
INSERT INTO stu VALUES('S_1008', 'zhouBa', 45, 'female');
INSERT INTO stu VALUES('S_1009', 'wuJiu', 85, 'male');
INSERT INTO stu VALUES('S_1010', 'zhengShi', 5, 'female');
INSERT INTO stu VALUES('S_1011', 'xxx', NULL, NULL);

下面进行操作演示:

1、查询所有列:select * from  表名;

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_11,color_FFFFFF,t_70,g_se,x_16

2、查询指定列:select 列名1,列名2,。。。from 表名;

eg:查询sname列和age列: 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_9,color_FFFFFF,t_70,g_se,x_16

3、条件查询:就是使用where关键词来限定,条件查询中也会用到逻辑用算符(在上面有写)

select *from 表名 where 限定语句;

eg:查找学生表中性别为女并且年龄小于50的所有信息。

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_17,color_FFFFFF,t_70,g_se,x_16

 eg:查找学号为s_1001或者姓名为lisi的

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_16,color_FFFFFF,t_70,g_se,x_16

 eg:查找学号为s_1001,s_1002,s_1003的学生。

注意:用or 而不是and。并且必须每个前面都要写sid=

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_20,color_FFFFFF,t_70,g_se,x_16

 范围查询:

上面这条语句还可以写成:列名 in (列值1,列值2):这样就可以省去不停的写id=这种繁琐的语句

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_19,color_FFFFFF,t_70,g_se,x_16

 eg:查找学号不是s_1001,s_1002,s_1003的学生。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_19,color_FFFFFF,t_70,g_se,x_16

eg:查询年龄为null:

用关键词 is null; 

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_12,color_FFFFFF,t_70,g_se,x_16

eg:查询年龄在20到40之间的学生记录:

列名 between 开始值 and 结束值;

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_15,color_FFFFFF,t_70,g_se,x_16

 eg:查询性别非男的学生记录:

SELECT * FROM stu WHERE gender!='male';

或者:SELECT * FROM stu WHERE gender<>'male';

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_12,color_FFFFFF,t_70,g_se,x_16

这就是常见的查询操作。 

模糊查询

类似于在浏览器中的关键词查询,例如:查询姓名中包含a的学生信息。这时候就要用到模糊查询了。

语法: 列名 like '表达式' //表达式必须是字符串

通配符:
_(下划线): 任意一个字符
%:任意0~n个字符,'张%'
 eg:“白_” 代表白某,而 “白%” 则代表白某或者白某某(任意长度)

我们先拿到stu表。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_10,color_FFFFFF,t_70,g_se,x_16

操作练习: 

1、查询姓名由三个字构成的学生信息

 SELECT * FROM stu WHERE sname LIKE '___';(此处为三个下划线)

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_13,color_FFFFFF,t_70,g_se,x_16

 2、查询姓名由五个字母构成,并且第五个字母为“i”的学生记录

SELECT * FROM stu WHERE sname LIKE '____i'; (前面为四个下划线)

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_13,color_FFFFFF,t_70,g_se,x_16

3、查询姓名以“z”开头的学生记录

SELECT * FROM stu WHERE sname LIKE 'z%';

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_13,color_FFFFFF,t_70,g_se,x_16

4、查询姓名中第二个字母为“i”的学生记录

SELECT * FROM stu WHERE sname LIKE '_i%'; 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_13,color_FFFFFF,t_70,g_se,x_16

 5、查询姓名中包含“a”字母的学生记录

SELECT * FROM stu WHERE sname LIKE '%a%';

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_13,color_FFFFFF,t_70,g_se,x_16

字段控制查询 

用到的表:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_20,color_FFFFFF,t_70,g_se,x_16

1、去除重复记录
去除重复记录(两行或两行以上记录中,列的数据都相同),比如说此表,我们想查询一共包含几种性别,我们显示性别列:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_9,color_FFFFFF,t_70,g_se,x_16

显示了重复性别,那么我们怎么去掉重复记录呢?

用到: DISTINCT关键字:

SELECT DISTINCT 列名 FROM 表名;

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_11,color_FFFFFF,t_70,g_se,x_16

 这样就去除了重复记录。

2、查询列的和

 SELECT 列名+列名 FROM 表名;(注意:必须是可以相加的列才行,否则会出错)

这里用下面这个表给大家做演示:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_20,color_FFFFFF,t_70,g_se,x_16

 eg:查看雇员的月薪与佣金之和

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_10,color_FFFFFF,t_70,g_se,x_16

 这里我们注意,emp2表中的一些数字加上null变成了null。例如第一行的sal为800.00但comm为null,加完后的结果不是800而是null。这种情况怎么办呢?

把null转为数字0 

把NULL转换成数值0的函数IFNULL :

SELECT 列名+IFNULL(要转换的列名,0) FROM emp;(这样就是把要转换的列名中的null都转换成0) 

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_12,color_FFFFFF,t_70,g_se,x_16

这样就相加正确。 

3、给列起别名

像这种,如果虚拟表的列名太长,不好记。我们也可以给它取个别名 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_12,color_FFFFFF,t_70,g_se,x_16

 语法1:select 要改的列名 as 新列名 from 表名;

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_15,color_FFFFFF,t_70,g_se,x_16

 语法2:将语法1的as去掉 换成空格;

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_13,color_FFFFFF,t_70,g_se,x_16

 排序

对表进行升序排列或者降序排列

order by 列名 asc/desc
asc 升序 desc 降序 默认不写的话是升序

用到的表: 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_20,color_FFFFFF,t_70,g_se,x_16

  查询所有记录,按薪水的升序排列:

SELECT * FROM emp2 ORDER BY sal ASC;  (默认不写asc也是升序)

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_20,color_FFFFFF,t_70,g_se,x_16

   降序就是 将asc改为desc就不在演示。

多列排序:当前面的列的值相同的时候,才会按照后面的列值进行排序

SELECT * FROM 表名 ORDER BY 列名 排序方法,列名2  排序方法; 

eg:查询所有雇员,按月薪降序排序,如果月薪相同时,按编号降序排序 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_20,color_FFFFFF,t_70,g_se,x_16

 我们可以看出sal相同的两行,按照empno的降序排列。

聚合函数

聚合函数是用来做纵向运算的函数 

 COUNT(列名):统计指定列不为NULL的记录行数;
MAX(列名):计算指定列的最大值,如果指定列是字符串类型,那么使用字符串排序运算;
MIN(列名):计算指定列的最小值,如果指定列是字符串类型,那么使用字符串排序运算;
SUM(列名):计算指定列的数值和,如果指定列类型不是数值类型,那么计算结果为0;
AVG(列名):计算指定列的平均值,如果指定列类型不是数值类型,那么计算结果为0;

 还是用上面的emp2来给大家一一演示

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_20,color_FFFFFF,t_70,g_se,x_16

一、count

1、查询表中的所有行数:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_9,color_FFFFFF,t_70,g_se,x_16

2、查询表中有佣金(comm)的所有行数 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_10,color_FFFFFF,t_70,g_se,x_16

 3、查询表中月薪(sal)大于2500的行数;

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_14,color_FFFFFF,t_70,g_se,x_16

 4、统计月薪和佣金之和大于2500

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_17,color_FFFFFF,t_70,g_se,x_16

 5、查询有佣金(comm)并且是领导(有mgr)的人数

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_13,color_FFFFFF,t_70,g_se,x_16

 二、sum和avg

1、查询所有雇员月薪和

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_9,color_FFFFFF,t_70,g_se,x_16

2、统计所有员工薪资(comm)的平均值

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_10,color_FFFFFF,t_70,g_se,x_16

3、得到所有员工的薪资的最大值和最小值

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_11,color_FFFFFF,t_70,g_se,x_16

 分组查询

上面我们查找工资之类的都是所有的员工,那么如果我们只想查找一个部门的呢?

关键字:GROUP BY

注意:如果查询语句中有分组操作,则select后面能添加的只能是聚合函数和被分组的列名

查询每个部门的部门编号和每个部门的工资和:

 1、查询各部门工资总和:

select  方法(列名)from 表名 group by  要分类的列名。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_13,color_FFFFFF,t_70,g_se,x_16

此时,我们发现,将部门通过编号分成了三类,但是我们并不知道,哪一个总和对应哪一个部门,这时就要用到语句:select 部门,方法(列名)from 表名 group by  要分类的列名。

 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_15,color_FFFFFF,t_70,g_se,x_16

2、查询每个部门的部门编号以及每个部门工资大于1500的人数 watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_19,color_FFFFFF,t_70,g_se,x_16

 HAVING子句

我们看上面的第二题:查询每个部门的部门编号以及每个部门工资大于1500的人数 ,是先有条件:工资大于1500,再分组,部门

而having关键字用于:先分部门,再有条件。

eg:查询工资总和大于9000的部门编号以及工资和: 

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_20,color_FFFFFF,t_70,g_se,x_16

 注:having与where的区别:
是在分组后对数据进行过滤,where是在分组前对数据进行过滤
后面可以使用分组函数(统计函数)
where后面不可以使用分组函数。
WHERE是对分组前记录的条件,如果某行记录没有满足WHERE子句的条件,那么这行记录不会参加分
组;而HAVING是对分组后数据的约束。

补充: 多列分组,分组的第一列出现相同的情况下,用第二列的值来分组

select 列名1,列名2 ,方法名(列名) ,from 表名 group by 列名1,列名2.

用到的表:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_11,color_FFFFFF,t_70,g_se,x_16

  -- 统计出stu表中每个班级的男女生各多少人
watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_17,color_FFFFFF,t_70,g_se,x_16

limit关键字和分页查询

limit用来限定查询结果的起始行,以及总行数(起到一个分页的效果,显示几行)

1、limit 开始下标,显示条数;//开始下标从0开始。

2、limit 显示条数;//表示默认从0开始获取数据

 用此表来展示:watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_20,color_FFFFFF,t_70,g_se,x_16

 1.查询5行记录,起始行从0开始

SELECT * FROM emp LIMIT 0, 5;

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_20,color_FFFFFF,t_70,g_se,x_16

2.查询10行记录,起始行从3开始 

SELECT* FROM emp LIMIT 3, 10;(因为数据没有那么多,所以只展示了符合要求的8行)

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAdOeZveaXpeaipuaDs-WutnQ=,size_20,color_FFFFFF,t_70,g_se,x_16

 分页查询

我们在实际开发中一般limit应用于分页查询这个功能上。

比如,我们现要将一个数据表分开,一页10条,分为n页,该怎么查呢?

解:第一页:limit 0,9;

        第二页:limit 10,19;

       。。。。

这样显然太麻烦。

此时,我们应设置变量,改变变量即可。eg:pageIndex 页码值 pageSize 每页显示条数

于是,用一条语句就可以代替上面的n条:

limit (pageindex-1)*pagesize,pagesize;

数据库的基础内容就这些。上面的所有都需要熟练掌握,逐一实现。