文章目录
- 导入数据库
- 数据库介绍
- 数据库使用
- 打开客户端连接MySQL
- 回顾总结
- 主键约束
- 注释 comment
- '和` (1左边的符号)
- 数据冗余
- 实例说明
- 事物
- SQL的分类
- truncate【删除】
- 数据库的数据类型
- is null 和 is not null (为空和不为空)
- 别名
- 去重 distinct
- 比较运算符 >,<,>=,<=,=,!=和<>
- and 和 or 同时满足多个条件and 满足其中一个 or
- in
- between x and y 包含x和y
- 模糊查询 like
- 排序 order by 关键字 (根据什么来排序)
- 分页查询 limit
- concat() 命名 函数
- 数值计算 + - * / (mod(7,2)等效 7%2);
- 日期相关函数
- innull(x,y) 函数
- 聚合函数
- 聚合函数练习:sum(),max(),min(),avg(),count(*)
- 和字符串相关函数
- 60个案例测试
- 24个案例测试
- 面试题分析:
- JDBC
- 回顾总结
导入数据库
- 方法一:在库里面
source 数据库名
- 方法二 直接吧sql文件拖入mysql
- MySQL默认端口号:3306 使用版本 5.1
数据库介绍
之前通过流去操作文件保存数据的弊端:
-
- 执行效率低
-
- 开发成本高
-
- 一般只能保存小量数据
-
- 只能保存文本数据
什么是DB
- DataBase 数据库: 代表文件集合
什么是DBMS
- DataBaseManagementSystem 数据库管理系统(软件) ,用于管理保存数据的文件集合,用于和程序员进行交互,常见的DBMS有:Oracle MySQL DB2 SQLServer Sqlite ,DBMS具备网络访问能力
什么是SQL
- Structured Query Language:结构化查询语言,用户程序员和DBMS进行交互,用于程序员告诉DBMS到底对数据进行什么操作的
数据库的分类(了解)
- 关系型数据库:经过数学理论验证可以将现实生活中的各种关系保存到数据库,这种就称为关系型数据库。保存数据以表为单位
- 非关系数据库:一般都是为了解决某些特定场景的问题比如:缓存,高并发访问,Redis数据库(以key-value形式保存数据)
常见的关系型数据
- MySQL: 属于Oracle公司的产品,08被Sun公司收购,09年Sun公司被Oracle收购,开源免费,被收购后发布5.5版本使用Oracle的部分技术,性能提高了30%以上,用户量增多,计划把MySQL闭源 原MySQL程序员离开Oracle创建了MariaDB 老板女儿Maria。市场排名第一
- Oracle: 排名第二,闭源 性能最高 收费最贵
- DB2: IBM公司产品 闭源项目
- SQLServer:微软公司产品 闭源
- Sqlite:轻量级数据库,安装包几十k,应用在嵌入式设备或移动设备上,
开源和闭源
-
开源:开放源代码 免费试用,通过卖服务盈利,社会上会有一些大牛程序员会无偿的维护和升级
-
闭源:不开放源代码 收费,通过卖产品+服务盈利 ,有大牛会攻击破坏,但是人家养了一群人维护升级
数据库使用
打开客户端连接MySQL
- 在终端中执行:
mysql -uroot -p 回车
如果有密码写密码 回车 如果没有密码则直接回车
和数据库相关的SQL
SQL格式:
- 可以有换行
- 最后以
;
结尾 - 关键字之间需要有空格(可以写多个空格,建议写一个)
查询所有数据库
show databases;
创建数据库
create database db1;
查看数据库详情
show create database db1;
【db1数据库名】
创建数据库指定字符集
create database db2 character set gbk/utf8;
【db2数据库名】
如:create database db2 character set gbk;
【创建一个gbk字符集的数据库】
删除数据库
drop database 数据库名;
如:drop database db2;
使用数据库
use db1;
【进入db1数据库】
表相关
查询所有表
-show tables;
创建表
create table 表名(字段1名 字段1的类型,字段2名 字段2的类型,.....);
如:create table person(name varchar(10),age int);
- 创建一个学生表(student) 保存学号id,姓名name,年龄age,语文chinese,数学math,英语english
create table student(id int,name varchar(10),age int,chinese int,math int,english int);
查看表详情
show create table 表名;
如:show create table person;
创建表时指定表的引擎和字符集
create table t1(name varchar(10)) engine=myisam charset=gbk;
【 t1 表名】
表的引擎
innodb
:支持数据库的高级操作如:外键、事务等,默认引擎myisam
:只支持基础的增删改查操作
查看表字段
- 查看表字段:
desc 表名;
- 表详情:
show create table 表名;
- 查询所有:
show tables;
删除表
drop table 表名;
修改表相关
1.修改表名
rename table 原名 to 新名;
如:rename table student to stu;
2.修改表的引擎和字符集
alter table 表名 engine=myisam/innodb charset = utf8/gbk;
如:alter table stu engine = myisam charset = gbk;
3.添加表字段
- 最后面:
alter table 表名 add 字段名 字段类型;
- 最前面:
alter table 表名 add 字段名 字段类型 first;
- xxx的后面:
alter table 表名 add 字段名 字段类型 after xxx;
- 创建表格
create table hero(name varchar(10));
- 添最后面
alter table hero add age int;
- 添最前面
alter table hero add id int first;
- 添name后面
alter table hero add sal int after name;
4.删除表字段
alter table 表名 drop 字段名;
如:alter table hero drop sal;
5.修改表字段的名字和类型
alter table 表名 change 原字段名 新字段名 新字段类型;
如:alter table hero change name heroname varchar(5);
6.修改表字段的类型和位置
alter table 表名 modify 字段名 类型 位置;
如:alter table hero modify age int first/(after xxx);
实例说明
- 1.创建数据库newdb并使用,里面创建员工表t_emp只有name字段 引擎为myisam 字符集为gbk;
create database newdb ;
查看数据库:show create database newdb;
create table t_emp(name varchar(10)) engine=myisam charset=gbk;
- 2.修改表名为emp;
rename table t_emp to emp;
- 3.修改引擎为innodb 字符集为utf8;
alter table emp engine=innodb charset=utf8;
- 4.添加部门编号字段deptno 在最后面
alter table emp add deptno int ;
- 5.添加员工编号 empno在最前面
alter table emp add empno int first;
- 6.添加salary字段在name的后面
alter table emp add salary int after name;
- 7.修改salary字段名为sal,吧sal放在empno后面
alter table emp change salary sal int;
alter table emp modify sal int after empno;
- 8.删除sal字段
alter table emp drop sal;
- 9.删除表
drop table emp;
- 10.删除数据库
drop database newdb;
数据相关
插入数据
create table emp(id int,name varchar(10),age int,sal int);
【 emp 表格名】
- 全表插入数据:
insert into emp values(1,'Tom',18,3000);
【emp 表格名】
- 指定字段插入数据:
insert into emp(name,age) values('Jerry',19);
insert into emp(name) values('李白');
【emp 表格名】
- 批量插入数据:
insert into emp values(3,'刘备',28,6000),(4,'张飞',20,5000),(5,'关羽',25,9000);
insert into emp (name,age) values('悟空',500),('八戒',400),('沙僧',200);
【emp 表格名】
查询数据
- 查询全部数据的全部字段信息
select * from emp;
- 查询所有员工的姓名和年龄;
select name,age from emp;
- 查询年龄在25岁以下的员工信息
select * from emp where age<25;
【emp 表格名】 - 查询工资3000块钱的员工姓名,年龄,工资
select name,age,sal from emp where sal=3000;
修改数据
- 修改所有类型的条件
update 表名 set 条件;
如:update emp set sal=6666;
- 修改Tom的工资为3333
update 表名 set 需要更改条件 where name='对象名全称'
如:update emp set sal=3333 where name='Tom';
- 修改30岁以下的工资为666;
update 表名 set 需要更改条件 where 对象名全称
如:update emp set sal=666 where age<30;
- 修改id等于3的名字为吕布 年龄为55 工资为20000;
update 表名 set 更改多个条件(用逗号隔开) where 对象全名称
如:update emp set name='吕布',age=55,sal=20000 where id=3;
- 修改工资为null的工资为800;
update 表名 set 更改条件 where null 用'is' 不用'='
如:update emp set sal=800 where sal is null;
删除数据
-
删除id=1的员工
delete from emp where id=1;
【emp 表格名】 -
删除年龄在25岁以下的员工
delete from emp where age<25;
【 emp 表格名】 -
删除全部数据
delete from emp;
【emp 表格名】
中文字符问题
set names gbk;
实例说明_上
- 1.创建hero表如果存在则先删除再创建,id 姓名name 类型type 金币money
drop table hero;
create table hero(id int,name varchar(10),type varchar(10),money int);
- 2.插入以下数据 1诸葛亮 法师18888 ,2 孙悟空 打野 18888,3 小乔 法师 6888,4黄总 射手 8888,5 刘备 战士 6888
insert into hero values(1,'诸葛亮','法师',18888),(2,'孙悟空','打野',18888),(3,'小乔','法师',6888),(4,'黄忠','射手',8888),(5,'刘备','战士',6888);
- 3.修改所有18888的为28888
update hero set money=28888 where money=18888;
- 4.修改所有打野为刺客
update hero set type='刺客' where type='打野';
- 5.删除价格为6888的英雄
delete from hero where money=6888;
- 6.修改孙悟空为猪八戒
update hero set name='猪八戒' where name='孙悟空';
- 7.删除id为1,2,3的英雄
delete from hero where id<4;
- 8.修改所有的英雄类型为已阵亡
update hero set type='已阵亡';
- 9.删除所有数据
delete from hero;
- 10, 删除表
drop table hero;
实例说明_下
- 1.创建数据库db2指定字符集为utf8 并使用 在数据库中,创建emp表里由id,name age,salary,部门名称(dept)
create database db2 character set utf8;
create table emp(id int,name varchar(10),age int,salary int,dept varchar(10));
- 2.往上面表格中插入 刘关张三人 和取经4人 工资在3000-8000随意设置,年龄随意,id为1-7,刘关张属于三国部,剩下4人属于取经部
insert into emp values(1,'刘备',34,1000,'三国部'),(2,'关羽',45,2211,'三国部'),(3,'张飞',24,2500,'三国部'),(4,'唐 僧',19,6000,'取经部'),(5,'孙悟空',1118,5000,'取经部'),(6,'猪八戒',23,4000,'取经部'),(7,'沙悟净',19,3000,'取经部');
- 3.给表格添加一个性别字段在年龄的后面
alter table emp add sex varchar(10) after age;
- 4.修改所有的性别字段值为男
update emp set sex='男' where sex is null;
- 5.添加一个貂蝉,性别女,年龄随意,工资为7000,部门为三国部
insert into emp values(8,'貂蝉',18,7000,'三国部','女');
- 6.修改年龄小于30岁的员工工资为200
update emp set salary=200 where age<30;
- 7.修改取经部的所有人性别为未知
update emp set sex='未知' where dept='取经部';
- 8.查询三国部的员工姓名和工资
select name,salary from emp where dept='三国部';
- 9.删除所有女员工
delete from emp where sex='女';
- 10.删除部门中工资低于5000的员工
delete from emp where salary<5000;
回顾总结
数据库相关SQL
- 查询所有数据库
show databases;
- 创建数据库
create database db1 character set utf8/gbk;
- 查看详情
show create database db1;
- 删除数据库
drop database db1;
- 使用数据库
use db1;
表相关SQL
- 查询所有表
show tables;
- 创建表
create table t1(name varchar(10),age int) engine=innodb/myisam charset=utf8/gbk;
- 查看详情
show create table t1;
- 表字段
desc t1;
- 删除表
drop table t1;
- 改表名
rename table t1 to t2;
- 改引擎字符集
alter table t1 engine=innodb/myisam charset=utf8/gbk;
- 添加字段
alter table t1 add age int first/ after xxx;
- 删除字段
alter table t1 drop age;
- 修改字段名字和类型
alter table t1 change sal salary int;
- 修改类型和位置
alter table t1 modify sal int first/after xxx;
数据相关
- 插入数据
insert into t1 (name,age) values(值1,值2),(值1,值2);
- 查询数据
select age,name from t1 where id<10;
- 修改数据
update t1 set age=18 where id=10;
- 删除数据
delete from t1 where id=10;
主键约束
- 主键:用于表示数据唯一性的字段称为主键
- 约束:事给表字段添加的限制条件
- 主键约束:限制主键字段值不能重复并且非空(唯一并且非空)
//创表:create table t1(id int primary key,name varchar(10));
//添数据:insert into t1 values(1,'Tom');
insert into t1 values(1,'Jerry');//失败 id重复了
insert into t1 values(null,'abc');//失败 不能为null
- 自增:
autp_increment
create table t2(id int primary key auto_increment,name varchar(10));
insert into t2 values(null,'aaa');
insert into t2 values(2,'bbb');
insert into t2 values(10,'ccc');
insert into t2 values(null,'2222');
1.当字段值为null的时候值会自动增长
2.自增字段值也可以手动赋值
3.增长的规则: 从曾杰出现的最大值基础上+1;
4.自增数值只增不减(delete清空表 自增数值并不清零);
注释 comment
-创建表声明字段的时候给字段添加的介绍
create table t3(id int primary key auto_increment comment '这是一个主键',name varchar(10) comment '这是员工姓名');
查看表详情:show create table 表名;
'和` (1左边的符号)
- ` :用于修饰表名和字段名 可以省略
create table `t4`(`id` int,`name` varchar(10));
- ’ : 用于修饰字符串
数据冗余
- 如果表设计不够合理,保存大量数据的同时可能随之会出现大量重复数据,这些重复数据的现象就称为数据冗余,通过拆分表的形式解决冗余问题。
实例说明
设计表保存一下数据:
1.集团总部下面的市场部下的市场a部的员工 刘备,工资8000,性别男,年龄25
2.教学部下 Java教师部的员工苍老师,工资100000,性别男,年龄18;
创建员工表
create table emp(id int primary key auto_increment,name varchar(10),salary int,gender varchar(5),age int,daptid int);
创建部门表
create table dept(id int primary key auto_increment,name varchar(10),parentid int);
插入数据
先插入部门表 再插入 员工表
insert into dept values(null,'集团总部',null);
insert into dept values(null,'市场部',1);
insert into dept values(null,'市场部a',2);
insert into emp values(null,'刘备',8000,'男',25,3);
insert into dept values(null,'教学部',4);
insert into emp values(null,'苍老师',100000,'男',18,5);
设计表保存以下数据2:
1.保存男装分类(category)下西服分类下的商品皮尔卡丹西服,价格9800,库存98件。
2.保存家用电器分类下,电视机分类下的小米电视,价格2500,库存108件
创建电器分类表
create table item(id int primary key auto_increment,name varchar(15),price int, num int,categoryid int);
创建部门分类表
create table category(id int primary key autoo_increment,name varchar(10),parentid int);
插入数据
intsert into category values(null,'男装',null),(null,'西服',1),(null,'家用电器',null),(null,'电视机',3);
insert into item values(null,'皮尔卡丹',9800,98,2),(null,'小米电视',2500,108,4);
事物
- 什么是事物: 事物是数据库中执行SQL语句的最小工作单元,可以保证事物内的多条SQL语句要么全部成功,要么全部失败。
- 查看数据库自动提交的状态:
show variables like '%autocommit%';
显示内容: on开 off关
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | ON |
+---------------+-------+
- 关掉自动提交: 0关闭 1 开启
set autocommit=0;
- 手动提交:
commit;
(关闭状态下写完需要手动提交)
- 手动提交:
- 测试转装:
create table person(id int,name varchar(10),money int);
insert into person values(1,'超人',500);
insert into person values(2,'钢铁侠',10000);
-
关掉自动提交:
set autocommit=0;
1.先让超人+2000;
update person set money=2500 where id=1;
2.开启另一个终端 验证,此时文件中的数据并没改掉:
usb 使用的数据库名;usb newdb;
person 表名:select * from person;
3.再让钢铁侠-2000;
update person set money=8000 where id=2;
4.执行提交:
commit;
-
回滚:
rollback;
(将内存中的修改回滚到上次提交的点)
update person set money=100 where id=1;
-
保存回滚点:
savepoint 自定义命名;
update person set money=100 where id=1;
savepoint s1;
update person set money=200 where id=1;
savepoint s2;
rollback to s1;
- 回顾:
- 查看自动提交状态:
show variables like '%autocommit%';
- 修改自动提交状态:
set autocommit=0/1;
- 提交:
commit;
- 回滚:
rollback;
- 保存回滚点:
savepoint 标识;
- 回滚到某个点:
rollback to 标识;
- 查看自动提交状态:
SQL的分类
DDL Data Definition Language
-数据定义语言,包括 create,alter,deop,truncate,不支持事物
打开客户端连接MySQL:mysql -uroot -p
DML Date Manipulation Language
- 数据操作语言, 包括 insert,delete,update,select(DQL);
DQL Date Query Language
- 数据查询语言,只包括select,和事物没有关系因为并没有修改数据
TCL Transaction Control Language
- 事物控制语言,包括 commit,rollback,savepoint,rollback to
DCL Data Control Language
-数据控制语言,用于处理分配用户权限相关的操作
truncate【删除】
truncate table 表名;
- 删除表示并且创建一个新表
- truncate,drop和delete的区别
- delete用于删除数据,使用delete清空表时自增数值不清零 执行效率最低
- drop 用于删除表 执行效率最高
- truncate 用于删除表并创建新的空表,执行效率比delete要高,而且则增数值会清零
数据库的数据类型
整数
- 常用整数有
int(m)
和bigint(m)
;m代表显示长度
age int(10)
赋值28; 则自动补零为:0000000028; - 创建表:
create table t_int(num int(10) zerofill);
- 赋值:
insert into t_int values(123);
- 查询:
select * from t_int;
结果:
+------------+
| num |
+------------+
| 0000000123 |
+------------+
浮点数
- 常用浮点数double(m,d) m代表总长度 d代表小数长度 23.346 m=5 d=3
decimal
超高精度浮点数,应用场景:涉及超高精度运算时使用
create table t_double(num double(5,3));
insert into t_double values(23.5678); #值为23.568
insert into t_double values(23.5); #值为23.500
字符串
char(m)
: 固定长度 m=10 abc 占10,效率高,最大255varchar(m)
:可变长度 m=10 abc 占3,节省空间,最大65535,如果超过255建议使用texttext(m)
:可变长度 最大65535
日期
date
:只能保存年月日time
:只能保存时分秒datetime
:保存年月日时分秒,默认值为null,最大值9999-12-31timestamp
(时间戳距离19700101 08:00:00):保存年月日时分秒,默认值为当前系统时间,最大值2038-01-19
create table t_time(t1 date,t2 time,t3 datetime,t4 timestamp);
insert into t_time values('2018-10-16',null,null,null);
insert into t_time values(null,'20:06:32','2008-11-22 18:22:11',null);
三方SQL工具:sqlyog
is null 和 is not null (为空和不为空)
- 1.查询emp表中没有上级领导mgr的员工编号empno,姓名ename,工资sal
select empno,ename,sal from emp where mgr is null;
- 2.查询emp表中没有奖金的员工姓名,工资,奖金
select ename,sal,comm from emp where comm is null;
- 3.查询有奖金的所有员工信息
select * from emp where comm is not null;
别名
1.将查询到的员工姓名ename改成’姓名’
查询select ename from emp;
方法一:select ename as '姓名' from emp;
方法二:select ename '姓名' from emp;
方法三:select ename 姓名 from emp;
连续更改多个内容:select ename 姓名,sal 工资 from emp;
去重 distinct
- 查询emp表中出现的所有职位job
select distinct job from emp;
比较运算符 >,<,>=,<=,=,!=和<>
- 1.查询工资小于等于1600的所有员工的姓名和工资
select ename,sal from emp where sal<1600;
- 2.查询部门编号是20的所有的员工姓名,职位和部门编号deptno
select ename,job,deptno from emp where deptno=20;
- 3.查询职位是manager的所有员工姓名和职位
select ename,job from emp where job='manager';
- 4.查询部门不是10号部门的所有员工姓名和部门编号(两种写法)
select ename,deptno from emp where deptno <>10;
select ename,deptno from emp where deptno !=10;
- 5.查询t_item表中单价price等于23的商品信息
select * from t_item where price=23;
筛选后:select title,price from t_tiem where price=23;
- 6.查询商品表中单价不等于8433的商品信息
select * from emp where price !=8433;
and 和 or 同时满足多个条件and 满足其中一个 or
and
等效java中的&&
(与
-or
等效java中的||
(或- 查询工资大于2000并且是10号部门的员工
select * from emp where sal>2000 and deptno=10;
- 1.查询不是10号部门并且工资大于等于1600的员工姓名,工资,部门编号
select ename,sal,deptno from emp where deptno!=10 and sal>1600;
- 2.查询部门是30号部门或者上级领导为7689的员工姓名,职位,上级领导和部门编号
select ename,job,mgr,deptno from emp where deptno=30 or mgr=7689;
- 3.查询有上级领导并且工资低于2000并且是20号部门的员工信息
select * from emp where mgr is not null and sal<2000 and deptno=20;
in
1.查询emp表中工资是 5000,1500,3000的员工信息
select * from emp where sal=5000 or sal=1500 or sal=3000;
select * from emp where sal in(5000,1500,3000);
between x and y 包含x和y
1.查询工资再2000到3000之间的员工姓名和工资
select ename,sal from emp where sal>=2000 and sal<=3000;
select ename,sal from emp where sal between 2000 and 3000;
模糊查询 like
_
: 代表单个未知字符%
:代表0或多个未知字符- 举例:
1.以a开头的字符串a%
2.以m结尾%m
3, 包含x%x%
4.第二个字符是a_a%
5.倒数第三个字母是m%m__
6.以a开头并且倒数第二个字母是ba%b_
- 案例
1.查询名字中包含a的所有员工姓名和工资
select ename,sal from emp where ename like '%a%';
2.查询标题中包含记事本的商品标题及商品价格
select title,price from t_item where title like '%记事本'% ;
3.查询单价低于100的记事本(title包含记事本)
select * from t_item where title like '%记事本%' and price<100;
4.查询单价在50-200之间的得力商品(title包含得力)
select * from t_item where price between 50 and 200 and title like '%活力得%';
5.查询商品分类为238和917的商品信息
select * from t_item where category_id in(238,917);
排序 order by 关键字 (根据什么来排序)
order by 关键字
,by 后面写排序的字段名称 默认是升序asc 升序
(可以不用写),desc 降序
1.查询所有员工的姓名和工资 按照工资升序排序
select ename,sal from emp order by sal;//默认升序
select ename,sal from emp order by sal desc; //后面加desc 降序
2.查询10号部门的所有员工信息 按照工资降序排序
select * from emp where deptno=10 order by sal desc;
3.查询所有带燃字的商品,按照单价升序排序
select * from t_item where title like '%燃%' order by price;
4.查询所有dell商品按照分类category_id 升序排序
select * from t_item where title like '%dell%' order by category_id;
5.查询所有员工按照部门升序排序 如果部门一致则按照工资降序排序
select * from emp order by deptno,sal desc;
6.查询所有商品分类和单价按照分类降序排序,如果分类相同则按照单价升序排序。
select category_id,price from t_item order by category_id desc,price asc;
分页查询 limit
limit
跳过的条数,请求的数量
第一页的数据limit 0,10;
第二页的十条limit 10,10;
第五页的20条limit (5-1)*20,20;
第8页的四条数据limit (8-1)*4,8;
- 1.查询员工表中工资降序的前五条数据
select * from emp order by sal desc limit 0,5;
- 2.查询员工中工资降序的第三页的4条数据
select * from emp order by sal desc limit 8,4;
- 3.查询商品表中价格升序的前10条数据
select * from t_item order by price limit 0,10;
- 4.查询商品表中价格低于100元的商品信息第三页的三条数据
select * from t_item where price<100 limit 6,3;
- 5.查询10号和30号部门的员工工资在前三名的员工信息
方法一select * from emp where deptno in(10,30) order by sal desc limit 0,3;
方法二select * from emp where deptno=10 or deptno=30 order by sal desc limit 0,3;
concat() 命名 函数
- 把concat内部的参数拼接到一起
- 1.查询员工姓名和工资,要求工资单位是元
select ename,concat(sal,'元') 工资 from emp;
数值计算 + - * / (mod(7,2)等效 7%2);
- 1,查询商品表中 每个商品的单机,库存及总价值(单价*库存);
select price,num,price*num from t_item;
- 2.查询员工表中每个员工的姓名,工资,及年终奖(五个月的工资)
select ename,sal,(sal*5) 年终奖 from emp;
日期相关函数
- 1.获取当前的年月日时分秒
select now();
- 2.获取当前日期 current
select curdate();
- 3.获取当前的时间
select curtime();
- 4.从年月日时分秒中提取年月日
select date(now());
- 5.从年月日时分秒中提取时分秒
select time(now());
- 6.从年月日时分秒中提取时间分量 年 月 日 时 分 秒
extract(year from now());
extract(month from now());
extract(day from now());
extract(hour from now());
extract(minute from now());
extract(second from now());
- now();是默认值,可以更改成需要更改的类型名
测试:select extract(year from now());
- 查询员工表中的所有员工姓名和入职的年份
select ename 姓名,extract(year from hiredate) 入职年份 from emp ;
- 7.日期格式化 date_ format(时间,格式);
%Y
: 四位年 2018%y
:两位年 18%m
:两位月 05%c
:一位月 5%d
:日%H
:24小时%h
:12小时%i
:分%s
:秒
select date_format(now(),'%Y年%m月%d日 %H时%i分%s秒');
- 查询商品名称和商品的上传日期(格式:x年x月x日);
select title 商品名称,date_format(created_time,'%Y年%m月%d日') 上传日期 from t_item;
- 把非标准的日期字符串转成标准的时间格式 str_to_date(时间字符串,格式)
14.08.2018 08:00:00
select str_to_date('14.08.2018 08:00:00','%d.%m.%Y %H:%i:%s');
innull(x,y) 函数
age=ifnull(x,18)
如果x的值为null 则age=18 如果不为null则 age=x
1.修改员工表中奖金为null的值为0
查询:select null from emp;
更改:update emp set comm=ifnull(comm,0);
查询:select null from emp;
聚合函数
用于多条数据进行统计
- 1.求和 sum(求和的字段名);
-查询emp表中10号部门的工资总和
查询10号部门工资:select sal 工资 from emp where deptno=10;
求和:select sum(sal) from emp where deptno=10;
- 2.平均值 avg(计算的字段名)
-查询emp表中所有的员工工资的平均值
select avg(sal) from emp;
- 3.最大值max (计算的字段名)
-查询30号部门的员工的最高奖金
select max(comm) 最高奖金 from emp where deptno=30;
- 4.最小值min(计算的字段名)
-查询商品表中价格最便宜的商品的单价
select min(price) 最便宜价格 from t_item;
- 5.统计数量 count(统计的字段名) 一般使用count(*);
-统计30号部门有多少人
select count(*) from emp where deptno=30;
聚合函数练习:sum(),max(),min(),avg(),count(*)
- 1.统计工资在2500以上的员工人数
select count(*) from emp sal>2500;
- 2.查询工资在1000到3000以内的最大奖金
select max(comm) from emp where sal>1000 and sal<3000;
select max(comm) from emp where between 1000 and 3000;
- 3.查询30号部门的最大奖金,最高工资,工资平均值,工资总和,并对查询结果起别名
select max(comm) 最大奖金,max(sal) 最高工资, avg(sal) 平均工资,sum(sal) 工资总和 from emp where deptno=30;
- 4.查询价格在100元以内的商品数量
select count(*) from t_item where price<100;
- 5.查询名字包含a的员工数量
select count(*) from emp where ename like '%a%';
和字符串相关函数
- 1.获取字符串的长度 char_length(str);
-获取所有员工的姓名和姓名的字符长度
select ename,char_length(ename) from emp;
- 2.获取字符串在另外一个字符串中出现的位置 inset(str,substr);
select instr('abcdefg','d');
//d出现在abcdefg中第四个 - 3.插入字符串 insert(str,start,length,new);
select insert('abcdefg',3,2,'m');
//从第三个开始 后面2个替换为m - 4.转大写upper(’***’); 转小写lower(’***’);
select upper('abc'), lower('NBA');
- 5.左边截取left(’*’,int)和右边截取right('’,int);
select left('abcdefg',2),right('abcdefg',2);
- 6.去两端空白 trim(’ * * );
select trim(' a b ');
- 7.截取字符串 substring(’***’,开始int,数量int);
select substring('abcdefg',3,2);
// cd - 8.重复 repeat(str,count);
select repeat('ab',2);
//abab - 9.替换 replace(str,old,new);
select replace('This is mysql,'my','your');
//my替换为your - 10.反转 reverse(str);
select reverse('abc');
//cba
60个案例测试
- 1.案例:查询没有上级领导的员工的编号,姓名,工资
select empno,ename,sal from emp where mgr is null;
- 2.案例:查询emp表中没有奖金的员工的姓名,职位,工资,以及奖金
select ename,job,sal,comm from emp where comm is null or comm=0;
- 3.案例:查询emp表中含有奖金的员工的编号,姓名,职位,以及奖金
select empno,ename,job,comm from emp where comm!=0 and comm is not null;
//0不大于0,所以必须and - 4.案例:查询含有上级领导的员工的姓名,工资以及上级领导的编号
select ename,sal,mgr from emp where mgr is not null;
- 5.案例:查询emp表中名字以‘S’开头的所有员工的姓名
select ename from emp where ename like 's%';
- 6.案例:查询emp表中名字的最后一个字符是’S’的员工的姓名
select ename from emp where ename like '%s';
- 7.案例:查询倒数的第2个字符是‘E’的员工的姓名
select ename from emp where ename like '%e_';
- 8.案例:查询emp表中员工的倒数第3个字符是‘N’的员工姓名
select ename from emp where ename like '%n__';
- 9.案例:查询emp表中员工的名字中包含‘A’的员工的姓名
select ename from emp where ename like '%a%';
- 10.案例:查询emp表中名字不是以’K’开头的员工的所有信息
select * from emp where ename not like 'k%';
- 11.案例:查询emp表中名字中不包含‘A’的所有员工的信息
select * from emp where ename not like '%a%';
- 12.案例:做文员的员工人数(job 中 含有 CLERK 的)
select count(*) from emp where job='clerk';
- 13.案例:销售人员 job: SALESMAN 的最高薪水
select max(sal) from emp where job='salesman';
- 14.案例:最早和最晚入职时间
select max(hiredate) 最晚入职,min(hiredate) 最早入职 from emp;
- 15.案例:查询类别 163的商品总库存量
select sum(num) from t_item where category_id=163;
- 16.案例:查询 类别 163 的商品
select * from t_item where category_id=163;
- 17.案例:查询商品价格不大于100的商品名称列表
select title from t_item where price<=100;
- 18.案例:查询品牌是联想,且价格在40000以上的商品名称和价格
select title,price from t_item where title like '%联想%' and price>40000;
- 19.案例:查询品牌是三木,或价格在50以下的商品名称和价格
select title,price from t_item where title like '%三木%' or price<50;
- 20.案例:查询品牌是三木、广博、齐心的商品名称和价格
select title ,price from t_item where title like '%三木%' or title like '%广播%' or title like '%齐心%';
- 21.案例:查询品牌不是联想、戴尔的商品名称和价格
select title price,title from t_item where title not like '%联想%' and title not like '%戴尔%';
- 22.案例:查找品牌是联想且价格大于10000的电脑名称
select title from t_item where title like '%联想%' and price>10000;
- 23.案例:查询联想或戴尔的电脑名称列表
select title from t_item where title like '%联想%' or title like '%戴尔%' ;
- 24.案例:查询联想、戴尔、三木的商品名称列表
select title from t_item where title like '%联想%' or title like '%戴尔%' or title like '%三木%';
- 25.案例:查询不是戴尔的电脑名称列表
select title from t_item where title not like ‘%戴尔%’; - 26.案例:查询所有是记事本的商品品牌、名称和价格
select item_type 名称,title 品牌 ,price 价格 from t_item where title like '%记事本%';
- 27.案例:查询品牌是末尾字符是’力’的商品的品牌、名称和价格
select title 品牌,item_type 名称,price 价格 from t_item where title like '%力';
- 28.案例:名称中有联想字样的商品名称
select title from t_item where title like '%联想%';
- 29.案例:查询卖点含有’赠’产品名称
select title from t_item where sell_point like '%赠%';
- 30.案例:查询emp表中员工的编号,姓名,职位,工资,并且工资在1000~2000之间。
select empno,ename,job,sal from emp where sal>1000 and sal<2000;
select empno,ename,job,sal from emp where sal beteeen 1000 and 2000;
- 31.案例:查询emp表中员工在10号部门,并且含有上级领导的员工的姓名,职位,上级领导编号以及所属部门的编号
select ename,job,mgr,deptno from emp where deptno=10 and mgr is not null;
- 32.案例:查询emp表中名字中包含’E’,并且职位不是MANAGER的员工的编号,姓名,职位,以及工资。
select empno,ename,job,sal from emp where ename like '%e%' and job!='manager';
- 33.案例:查询emp表中10号部门或者20号部门中员工的编号,姓名,所属部门的编号
select empno,ename,deptno from emp where deptno=10 or deptno=20;
select empno,ename,deptno from emp where deptno in(10,20);
- 34.案例:查询emp表中没有奖金或者名字的倒数第2个字母不是T的员工的编号,姓名,职位以及奖金
select empno,ename,job,comm from emp where comm!=0 or ename not like '%t_';
- 35.案例:查询工资高于3000或者部门编号是30的员工的姓名,职位,工资,入职时间以及所属部门的编号
select ename,job,sal,hiredate deptno from emp where sal>3000 or deptno=30;
- 36.案例:查询不是30号部门的员工的所有信息
select * from emp where deptno!=30;
- 37.案例:查询奖金不为空的员工的所有信息
select * from emp where comm!=0 or is not null;
- 38.案例:查询emp表中所有员工的编号,姓名,职位,根据员工的编号进行降序排列
select empno,ename,job from emp order by empno desc;
- 39.案例:查询emp表中部门编号是10号或者30号中,所有员工姓名,职务,工资,根据工资进行升序排列
select ename,job,sal from emp where deptno=10 or deptno=30 order by sal;
- 40.案例:查询emp表中所有的数据,然后根据部门的编号进行升序排列,如果部门编号一致,根据员工的编号进行降序排列
select * from emp order by deptno, empno desc;
- 41.案例:查询emp表中工资高于1000或者没有上级领导的员工的编号,姓名,工资,所属部门的编号,以及上级领导的编号,根据部门编号进行降序排列,如果部门编号一致根据工资进行升序排列。
select empno,ename,sal,deptno,mgr from emp where sal>1000 or mgr is null order by deptno desc,sal;
- 42.案例:查询emp表中名字中不包含S的员工的编号,姓名,工资,奖金,根据工资进行升序排列,如果工资一致,根据编号进行降序排列
select empno,ename,sal,comm from emp where ename not like '%s%' order by sal,empno desc;
- 43.案例:统计emp表中员工的总数量
select count(ename) from emp;
select count(*) from emp;
- 44.案例:统计emp表中获得奖金的员工的数量
select count(ename) from emp where comm!=0;
- 45.案例:求出emp表中所有的工资累加之和
select sum(sal) from emp;
- 46.案例:求出emp表中所有的奖金累加之和
select sum(comm) from emp;
- 47.案例:求出emp表中员工的平均工资
select avg(sal) from emp;
- 48.案例:求出emp表中员工的平均奖金
select avg(comm) from emp;
- 49.案例:求出emp表中员工的最高工资
select max(sal) from emp;
- 50.案例:求出emp表中员工编号的最大值
select max(empno) from emp;
- 51.案例:查询emp表中员工的最低工资。
select min(sal) from emp;
- 52.案例:查询emp表中员工的人数,工资的总和,平均工资,奖金的最大值,奖金的最小值,并且对返回的列起别名。
select count(ename) 员工人数,sum(sal) 工资总和,avg(sal) 平均工资,max(comm) 最多奖金,min(comm) 最少奖金 from emp;
- 53.案例:查询emp表中每个部门的编号,人数,工资总和,最后根据人数进行升序排列,如果人数一致,根据工资总和降序排列。
select deptno 编号总数,count(ename) 总人数,sum(sal) 工资总和 from emp group by deptno order by count(ename),sum(sal) desc;
方法二 用别名:
select deptno 编号总数,count(ename) 总人数,sum(sal) 工资总和 from emp group by 编号总数 order by 总人数,工资总和 desc;
- 54.案例:查询工资在1000~3000之间的员工信息,每个部门的编号,平均工资,最低工资,最高工资,根据平均工资进行升序排列。
select deptno,avg(sal),min(sal),max(sal) from emp where sal>1000 and sal<3000 group by deptno order by avg(sal);
- 55.案例:查询含有上级领导的员工,每个职业的人数,工资的总和,平均工资,最低工资,最后根据人数进行降序排列,如果人数一致,根据平均工资进行升序排列
select count(ename) 人数,job,sum(sal),avg(sal) 平均工资,min(sal) from emp where mgr is not null group by job order by 人数 desc,平均工资;
//用别名命名 - 56.案例:查询工资在1000~3000之间每一个员工的编号,姓名,职位,工资
select empno,ename,job,sal from emp where sal>1000 and sal<3000 group by sal;
- 57.案例:查询emp表中奖金在500~2000之间所有员工的编号,姓名,工资以及奖金
select empno,ename,sal,comm from emp where comm>500 and comm<2000;
- 58.案例:查询员工的编号是7369,7521,
select * from emp where empno=7396 or empno=7521;
- 59.案例:查询emp表中,职位是ANALYST,
select * from emp where job='analyst';
- 60.案例:查询emp表中职位不是ANALYST,
select * from emp where job!='analyst';
数学相关函数
- 1.向下取整 floor(num);
select floor(3.84)
- 2.四舍五入 round(num);
select round(3.84);
- round(num,m) m 代表小数数位
select round(4.431623,3);
//4.432 - 3.非四舍五入 truncate(num,m);
select truncate(3.84567,3);
//3.845 - 4.随机数 rand() 0-1
5-10 0-5select floor(rand()*6) + 5;
3-8 0-5select floor(rand()*7) +3;
分组查询
-
分组查询通常和聚合函数结合使用,以组为单位进行统计
-
一般情况下,题目中每个xxx(如部门) 就在group by 后面写xxx(如部门)
-
1.查询每个部门的最高工资
select deptno,max(sal) from emp group by deptno;
-
2.查询每个部门的平均工资
select deptno,avg(sal) from emp group by deptno;
-
3.查询每个分类下的商品的最低价格
select category_id,min(price) from t_item group by category_id;
-
4.查询工资大于1500的所有员工中每个部门的人数
select deptno,count(*) from emp where sal>1500 group by deptno;
-
5.查询每个领导的手下人数
select mgr,count(*) from emp where mgr is not null group by mgr;
-
6.查询每个商品分类的库存总量
select category_id,sum(num) from t_item group by category_id;
-
1.案例:查询emp表中每个部门的编号,人数,工资总和,最后根据人数进行升序排列,如果人数一致,根据工资总和降序排列。
select deptno 编号总数,count(ename) 总人数,sum(sal) 工资总和 from emp group by deptno order by count(ename),sum(sal) desc;
方法二 用别名:
select deptno 编号总数,count(ename) 总人数,sum(sal) 工资总和 from emp group by 编号总数 order by 总人数,工资总和 desc;
-
2.案例:查询工资在1000~3000之间的员工信息,每个部门的编号,平均工资,最低工资,最高工资,根据平均工资进行升序排列。
select deptno,avg(sal),min(sal),max(sal) from emp where sal>1000 and sal<3000 group by deptno order by avg(sal);
-
3.案例:查询含有上级领导的员工,每个职业的人数,工资的总和,平均工资,最低工资,最后根据人数进行降序排列,如果人数一致,根据平均工资进行升序排列
select count(ename) 人数,job,sum(sal),avg(sal) 平均工资,min(sal) from emp where mgr is not null group by job order by 人数 desc,平均工资;
//用别名命名 -
如果需要使用多个字段进行分组 直接在group by 后面多写个字段名通过逗号分隔
1.查询每个部门下每个领导的手下人数
select deptno,mgr,count(*) from emp where mgr is not null group by deptno,mgr;
having 不能单独使用 套 group by 使用
- where 后面只能写普通字段的条件不能写聚合函数
- having后面可以写普通字段页可以写聚合函数,但是推荐在having后面只写聚合函数
- having 写在 group by 的后面
- 先后顺序:
select * from 表名 where ...... group by xxx having ......order by .... limit ....;
- 1.查询每个部门的平均工资,要求平均工资大于2000
select deptno,avg(sal) from emp group by deptno having avg(sal)>2000;
- 2.查询每个分类的平均单价,过滤掉平均单价低于100的;
select category_id,avg(price) from t_item group by category_id having avg(price)>=100;
实例说明
- 1.查询每个分类商品的库存总量,要求总量高于19999;
select category_id,sum(num) 库存总量 from t_item group by category_id having 库存总量>19999;
- 2.查询分类id为238和917的两个分类的平均单价各是多少
select category_id id,avg(price) from t_item group by category_id having id=238 or id=917;
方法二:select category_id,avg(price) from t_item where category_id in(238,917) group by category_id;
- 3.查询emp表中每个部门的平均工资高于2000的部门编号,部门人数,平均工资最后根据平均工资降序排序
select deptno,count(*),avg(sal) 平均工资 from emp group by deptno having 平均工资>2000 order by 平均工资 desc;
- 4.查询emp表中工资在1000-3000之间的员工,每个部门的编号,工资总和,平均工资,要求过滤掉平均工资低于2000的部门,按照工资共和降序排序;
select deptno,sum(sal) 总工资,avg(sal) 平均工资 from emp where sal between 1000 and 3000 group by deptno having 平均工资>=2000 order by 总工资 desc;
- 5.查询emp表中不是以s开头每个职位的名字,人数,工资总和,最高工资,过滤掉平均工资时3000的职位,根据人数升序排序,如果一致根据工资总和降序排序
select job,count(*),sum(sal),max(sal) from emp where job not like 's%' group by job having avg(sal)!=3000 order by count(*),sum(sal) desc;
- 6.查询emp表每年入职的人数
select extract(year from hiredate) y,count(*) from emp group by y;
子查询
- 子查询
select * from emp where sal=(select max(sal) from emp);
- 1.查询emp表工资最高的员工信息
select max(sal) from emp;
select * from emp where sal=5000;
- 2.查询emp表中工资高于平均工资的员工
select * from emp where sal>(select avg(sal) from emp);
- 3.查询和jones相同工作的员工信息
select * from emp where job=(select job from emp where ename='jones') and ename!='jones';
- 4.查询工资最低的员工的所在部门同事信息
求最低工资-
select min(sal) from emp;
-通过最低工资得到这个员工部门编号:
select deptno from emp where sal=(select min(sal) from emp);
-通过部门编号找到其他员工信息,并排除最低工资:
select * from emp where deptno=(select deptno from emp where sal=(select min(sal) from emp)) and sal!=(select min(sal) from emp);
- 5.查询最后入职的员工
//查询全部时间select date_format(hiredate,'%Y年%m月%d日') c from emp;
查询最晚时间:select max(hiredate) from emp;
select * from emp where hiredate=(select max(hiredate) from emp);
- 6.查询king的部门编号和部门名称
-得到部门编号
select deptno from emp where ename='king';
-通过编号得到部门名称
select deptno,dname from dept where deptno=(select deptno from emp where ename='king');
- 7.查询有员工的部门信息(需要两张表);
-得到员工表出现的部门编号
select distinct deptno from emp;
-通过部门编号得到部门信息
select * from dept where deptno in (select distinct deptno from emp);
- 8.查询平均工资最高的部门信息(史诗级难度!!)
-得到每个部门的平均工资
select deptno,avg(sal) from emp group by deptno;
-得到最高的平均工资
select avg(sal) a from emp group by deptno order by a desc limit 0,1;
-通过最高的平均工资得到对应的部门
select deptno from emp group by deptno having avg(sal)=(select avg(sal) a from emp group by deptno order by a desc limit 0,1);
-通过部门编号得到部门信息
select * from dept where deptno in(select deptno from emp group by deptno having avg(sal)=(select avg(sal) a from emp group by deptno order by a desc limit 0,1));
- 子查询可以写在什么位置
1.写在where或having后面,当作查询条件的值
2.写在创建表的时候 把查询结果保存成一张新的表
create table emp_20 as (select * from emp where deptno=20);
3.写在from后面 当成一个虚拟表 必须有一个名写在最后面
select * from emp where deptno=20;
select ename,sal from(select * from emp where deptno=20) newtable;
关联查询
- 同时查询多张表的数据称为关联查询
- 1.查询每一个员工的姓名和对应的部门名称
拆分:
查询内容:select e.ename,d.dname
命别名:from emp e,dept d
他们的关系:where e.deptno=d.deptno;
合并:
select e.ename,d.dname from emp e,dept d where e.deptno=d.deptno;
- 2.查询在new york工作的员工信息
分行的形式展现更容易理解
select *
from emp e,dept d
where e.emp=d.deptno
and d.loc='new york';
- 3.查询上标题和所对应的分类名称
分行的形式展现更容易理解
select t.title,c,name
from t_item,t_item_category c
where i.category_id=c.id;
笛卡尔积
- 等值连接和内连接查询到的内容一样,都为两张表中有关联关系的数据(
-如果关联查询不写关联关系则结果为两张表的乘积,这个乘积称为笛卡尔积。 - 笛卡尔积为一种错误的查询结果,切记工作中不要出现
等值连接和内连接
- 等值连接:
select * from A,B where A.x=B.x and A.age=18;
- 内连接:
select * from A join B on A.x=B.x where A.age=18;
- 1.查询每一个员工的姓名和对应的部门名称
select e.ename,d.dname
from emp e join dept d
on e.deptno=d.deptno;
外连接
- 内连接和等值连接查询到的时交集部分的数据,外连接查询到的是某一张表的全部数据+另外一张表的交集数据;
- 左/右外连接:
select * from A left/right join B on A.x=B.x where A.age=18;
insert into emp(empno,ename) values(10010,'Tom');
- 1.查询所有员工姓名和对应的部门名称
select e.ename,d.dname
from emp e left join dept d
on e.deptno=d.deptno;
关联查询总结
- 关联查询的查询方式: 等值连接 内连接和外连接
- 如果想查询的数据为两张表的交集数据使用等值连接或内链接(推荐)
- 如果查询的数据是一张表的全部数据和另外一张表的交集数据则使用外连接
24个案例测试
- 1.每个部门的人数,根据人数排序
select deptno,count(*) from emp group by deptno;
- 2.每个部门中,每个主管的手下人数
select deptno,mgr,count(*) from emp where mgr is not null group by deptno,mgr;
查询两张表:select d.deptno,e.mgr,count(e.ename)
右外查询:from emp e right join dept d
内链接:
on e. deptno=d.deptno
where e.mgr is not null
group by d.deptno,e.mgr;
- 3.每种工作的平均工资
select job 工作名,avg(sal) 平均工资 from emp group by job ;
- 4.每年的入职人数
select extract(year from hiredate) y,count(*) 入职人数 from emp group by y;
- 5.少于等于3个人的部门信息
两张表:
select d.*,count(ename) c
from emp e right join dept d
on e.deptno=d.deptno
group by d.deptno
having c<=3;
- 6.拿最低工资的员工信息
select * from emp where sal=(select min(sal) from emp);
- 7.只有一个下属的主管信息
查询上级id信息方法:select * from emp where mgr is not null group by mgr having count(*)=1;
正确答案:
select mgr from emp where mgr is not null group by mgr having count(*)=1;
select * from emp where empno in(select mgr from emp where mgr is not null group by mgr having count(*)=1);
- 8.平均工资最高的部门编号
-得到每个部门的平均工资
select deptno,avg(sal) from emp group by deptno;
-得到最高的平均工资
select avg(sal) a from emp group by deptno order by a desc limit 0,1;
-通过最高的平均工资得到对应的部门
select deptno from emp group by deptno having avg(sal)=(select avg(sal) a from emp group by deptno order by a desc limit 0,1);
拓展:-通过部门编号得到部门信息
select * from dept where deptno in(select deptno from emp group by deptno having avg(sal)=(select avg(sal) a from emp group by deptno order by a desc limit 0,1));
- 9.下属人数最多的人,查询其个人信息
select count(*) from emp group by mgr order by count(*) desc limit 0,1;
select * from emp group by mgr having count(*)=(select count(*) from emp group by mgr order by count(*) desc limit 0,1);
得到最多的下属人数;select count(*) c from emp group by mgr order by count(*) desc limit 0,1;
通过人数查询对应的领导编号:select mgr from emp group by mgr having count(*)=(select count(*) c from emp group by mgr order by c desc limit 0,1);
ps:查询条件不能同时由2个 select mgr,count(*) 报错。
通过领导编号得到个人信息
select * from emp where empno in(select mgr from emp group by mgr having count(*)=(select count(*) c from emp group by mgr order by c desc limit 0,1));
- 10.拿最低工资的人的信息
select * from emp having min(sal);
select * from emp where sal=(select min(sal) from emp);
- 11.最后入职的员工信息
方法一:select * from emp order by hiredate desc limit 0,1;
方法二:
select max(hiredate) from emp;
select * from emp where hiredate=(select max(hiredate) from emp);
- 12.工资多于平均工资的员工信息
select avg(sal) from emp;
select * from emp where sal>(select avg(sal) from emp);
- 13.查询员工信息,部门名称
select e.*,d.dname 部门名称
from emp e join dept d
where e.deptno=d.deptno;
- 14.员工信息,部门名称,所在城市
select e.*,d.dname 部门名称,d.loc 所在城市
from emp e,dept d
where e.deptno=d.deptno;
- 15.DALLAS 市所有的员工信息
select *
from emp e join dept d
,替换成join后, 下面的where可以用on代替
on e.deptno=d.deptno
and d.loc='dallas';
- 16.按城市分组,计算每个城市的员工数量
select d.loc,count(ename)
from emp e right join dept d
on e.deptno=d.deptno
group by d.loc;
- 17.查询员工信息和他的主管姓名
select e.*,m.ename
from emp e join emp m
on e.mgr=m.empno;
-建新表 查看效果:
create table t_dept(id int,name varchar(10),parent_id int);
insert into t_dept values(1,'集团总部',null),(2,'市场部',1),(3,'教学部',1),(4,'java教学部',3);
-查询每个部门的名称和上级部门的名称
select d.name,m.name
from t_dept d join t_dept m
on d.parent_id=m.id;
- 18.员工信息,员工主管名字,部门名
select e.ename,m.ename,d.dname
from emp e join emp m
on e.mgr=m.empno
join dept d
on e.deptno=d.deptno;
- 19.员工和他所在部门名
select e.ename 员工名,d.dname 部门名
from emp e join dept d
on e.deptno=d.deptno;
- 20.案例:查询emp表中所有员工的姓名以及该员工上级领导的编号,姓名,职位,工资
//错误写法:select mgr,ename,job,sal from emp where mgr is not null group by mgr;
一张表当两张表用:
select e.ename,m.empno,m.ename,m.job,m.sal
from emp e left join emp m
on e.mgr = m.empno;
- 21.案例:查询emp表中名字中没有字母’K’的所有员工的编号,姓名,职位以及所在部门的编号,名称,地址
写法一:
select e.empno,e.ename,e.job,d.deptno,d.dname,d.loc
from emp e,dept d
where e.deptno=d.deptno
and e.ename not like '%k%';
写法二外连接:
select e.empno,e.ename,e.job,d.*
from emp e left join dept d
on e.deptno=d.deptno
where e.ename not like '%k%';
- 21.案例:查询dept表中所有的部门的所有的信息,以及与之关联的emp表中员工的编号,姓名,职位,工资
写法一:
select d.*,e.empno,e.ename,e.job,e.sal
from emp e,dept d
where e.deptno=d.deptno;
方法二 外连接:
select d.*,e.empno,e.ename,e.job,e.sal
from emp e right join dept d
on e.deptno=d.deptno
表设计之关联关系
一对一
- 什么是一对一关系: 有ab两张表,其中a表的一条数据对应b表的一条数据,同时b表的一条数据页对应a表中的一条数据
- 应用场景: 用户表和用户信息拓展表
如:用户名 密码 昵称 头像 性别 手机号 地址 邮箱。。。。。 - 外键:表中用于建立关系的字段称为外键,一张表可能有多个外键,但只会有一个主键
- 如何建立关系:在从表中添加外键指向主表的主键
- 练习: 创建表保存一下数据:表名 user 和 userinfo
user中:id 用户名wukong 密码:abcd userinfo中:昵称:悟空 性别 男 地址:大唐
null wzt admin 武则天 女 大陆
null superman 132465 超人 男 铁岭
代码如下
create table user(id int primary key auto_increment,username varchar(10),password varchar(10));
create table userinfo(userid int,nickname varchar(10),sex varchar(10),address varchar(10));
insert into user values(null,'wk','abcd'),(null,'wzt','admin'),(null,'Superman','123456');
insert into userinfo values(1,'悟空','男','花果山'),(2,'武则天','女','大陆'),(3,'超人','男','铁岭');
- 1.查询每个用户名对应的昵称
select u.username,ui.nickname
from user u join userinfo ui
on u.id=ui.userid;
- 2.查询超人的用户名
select u.username
from user u join userinfo ui
on u.id=ui.userid
where ui.nickname='超人';
- 3.查询性别是男的用户名和密码
select u.username,u.password
from user u join userinfo ui
on u.id=ui.userid where ui.sex='男';
- 4.查询是否存在 用户名: wukong 密码: abd的用户名 (查询符合条件的数据条数)
select count(*) from user where username='wukong' and password='adb';
一对多
- 什么是一对多: 有ab两张表,a表中的一条数据对应b表中的多条数据,同时b表中的一条数据对应a表中的一条
- 应用场景: 用户表和部门表,商品表和分类表
- 如何建立关系:在多的一端添加外键指向另外一张表的主键
create table emp(id int primary key auto_increment,name varchar(10),deptid int);
create table dept(id int primary key auto_increment,name varchar(10));
insert into emp values(null,'猪八戒',1),(null,'白骨精',2),(null,'蜘蛛精',2);
insert into dept values(null,'神仙'),(null,'妖怪');
- 1.查询每个员工的姓名和对应的部门名称
select e.name,d.name
from emp e join dept d
on e.deptid=d.id;
- 2.查询妖怪部的员工姓名
select e.name
from emp e join dept d
on e.deptid=d.id where d.name='妖怪';
多对多
- 什么是一对多: 有ab两张表,a表中的一条数据对应b表中的多条数据,同时b表中的一条数据对应a表中的多条
- 应用场景:老师表和学生表
- 如何建立关系: 通过第三张关系表保存两张主表的关系
- 练习:
创建老师表,学生表和关系表
create table teacher(id int primary key auto_increment,name varchar(10));
create table student(id int primary key auto_increment,name varchar(10));
create table t_s(tid int,sid int);
insert into teacher values(null,'苍老师'),(null,'传奇老师');
insert into student values(null,'小王'),(null,'小刘'),(null,'小张');
- 1.往以上表中保存苍老师的学生小刘和小丽,传奇老师的学生小刘,小王和小丽
insert into teacher values(null,'苍老师'),(null,'传奇老师');
insert into student values(null,'小王'),(null,'小刘'),(null,'小张');
insert into t_s values(1,1),(1,3),(2,1),(2,2),(2,3);
- 2.查询每个学生姓名和对应的老师姓名
select s.name,t.name
from student s join t_s ts
on s.id=ts.sid
join teacher t
on t.id=ts.tid;
- 3.查询苍老师的学生都有谁
select s.name
from student s join t_s ts
on s.id=ts.sid
join teacher t
on t.id =ts.tid where t.name='苍老师';
- 4.查询小刘的老师是谁
select t.name
from student s join t_s ts
on s.id=ts.sid
join teacher t
on t.id =ts.tid where s.name='小刘';
自关联
- 在当前表中添加外键 外键的值指向当前表的主键,这种关联方式称为自关联
create table person(id int primary key auto_increment,name varchar(10),mgr int);
保存一下数据:如来→唐僧→悟空→猴崽子
insert into person values(null,'如来',null),(null,'唐僧',1),(null,'悟空',2),(null,'猴崽子',3);
- 1.查询每个人的名字和上级的名字
//左边表有个最上级如来,所以用左外连接让如来显示出来
select p.name,m.name 上级
from person p left join person m
on p.mgr=m.id;
表设计案例:权限管理
- 实现权限管理功能需要准备三种主表和两种关系表
- 创建表:
create table user(id int,name varchar(10));
create table role(id int,name varchar(10));
create table module(id int,name varchar(10));
create table u_r (uid int,rid int);
create table r_m (rid int,mid int);
- 插入数据:
insert into user values(1,'刘德华'),(2,'凤姐');
insert into role values(1,'刘德华'),(2,'男会员'),(3,'女游客'),(4,'女管理员');
insert into module values(1,'男浏览'),(2,'男发帖'),(3,'女浏览'),(4,'女发帖'),(5,'女发帖'),(6,'女删帖');
- 保存校色和权限的关系:
insert into r_m values(1,1),(2,1),(2,2),(3,3),(4,3),(4,4),(4,5);
- 保存用户和角色的关系:刘德华男会员和女游客 凤姐: 女管理员和男游客
insert into u_r values(1,2),(1,3),(2,1),(2,4);
- 1.查询每个用户的权限有哪些
select u.name,m.name
from user u join u_r ur
on u.id = ur.uid
join r_m rm
on rm.rid=ur.rid
join module m
on m.id=rm.mid;
- 2.查询凤姐的权限
select u.name,m.name
from user u join u_r ur
on u.id=ur.uid
join r_m rm
on rm.rid=ur.rid
join module m
on m.id=rm.mid where u.name='凤姐';
- 3.查询拥有男浏览权限的用户有谁
select u.name,m.name
from user u join u_r ur
on u.id=ur.uid
join r_m rm
on rm.rid=ur.rid
join module m
on m.id=rm.mid where m.name='男浏览';
视图
- 数据库中包含多种对象,表和试图都是数据库中的对象,视图可以理解成一张虚拟表,试图本质就是取代了一段sql查询语句
- 为什么使用视图:因为有些数据的查询需要写大量的SQL语句,每次书写比较麻烦,通过使用视图相当于把当了的SQL查询语句进行保存,下次从视图中查询就不用再次写大量SQL语句,从而提高开发效率;
试图格式:
create view 视图名 as(子查询);
创建:create view v_emp_10 as (select * from emp where deptno=10);
插入:delete from emp where sal=1300;
查询:select * from v_emp_10;
- 1.创建一个没有工资的视图
create view v_emp_nosal as (select empno,ename,comm,mgr from emp);
select * from v_emp_nosal;
- 2.创建视图,视图中显示每个部门的工资总和,平均工资,最高工资,最低工资;
create view v_emp_xxx as (select deptno,sum(sal),avg(sal),max(sal),min(sal) from emp group by deptno);
select * from v_emp_xx;
视图的分类:
- 1.简单的视图:创建视图的时候不包含:去重,分组,函数,关联查询的视图称为简单视图,可以对视图中的数据进行增删改查
- 2.复杂视图: 和简单视图相反,只能进行查询操作
- 简单视图的增删改操作 操作方式和操作table一样
- 插入数据:
查视图:show tables;
insert into v_emp_10 (empno,ename,deptno) values (10011,'悟空',10);
insert into v_emp_10 (empno,ename,deptno) values (10012,'八戒',20);#(数据污染,只能在总表中查出来,v_emp_10中查不到)
- 数据污染:往三视图中插入一条在视图中不显示但是在原表中显示的数据,称为数据污染
- 通过 with check option 关键字解决数据污染问题
create view e_emp_20 as (select * from emp where deptno=20) with check option;
- 测试:
insert into e_emp_20 (empno,ename,deptno) values (10013,'刘备',20);
//成功
insert into e_emp_20 (empno,ename,deptno) values (10014,'张飞',30);
//失败 deptno!=20; - 删除和修改: 只能操作视图中存在的数据
- 别名:如果创建视图时使用别名 则 操作视图时只能使用别名;
create view v_emp_30 as (select ename name from emp where deptno=30);
select * from v_emp_30 where ename='james';
视图总结:
- 1.视图是数据库中的对象,可以理解成一张虚拟的表,本质就是一段SQL语句
- 2.作用:重用SQL,隐藏敏感字段
- 3.分类:简单视图(不包含去重 分组 函数 关联查询,可以增删改查)和复杂视图(反之,查询)
- 4.通过with check option 解决数据污染
- 5.删除和修改时, 只能操作视图中存在的数据
- 6.起了别名 只能用别名
约束
- 约束:约束是创建表时给字段添加的限制条件
非空约束 not null
- 字段值不能为null
create table t1(id int,age int not null);
insert into t1 values(1,18);//成功
insert into t1 values(2,null);//失败
唯一约束 unique
- 字段的值不能重复
create table t2(id int,age int unique);
insert into t2 values(1,19);//成功
insert into t2 values(2,19);//失败
主键约束
- 字段的值唯一且非空
- 创建表时添加主键约束:
create table t3(id int primary key,age int);
- 创建表之后添加主键约束:
create table t3(id int,name varchar(10));
alter table t3 add primary key(id);
- 删除主键约束
alter table t3 drop primary key;
自增
- 数值只增不减
- 从历史最大值的基础上+1
- 字段赋值为null的时候自动+1
- 使用delete 删除全表数据 自增数值不变
- 使用truncate 自增清零
默认约束 default
- 给字段添加默认值 当插入数据不给该字段赋值时,默认值生效
create table t4(id int,age int default 10);
insert into t4 alues(1,20);
insert into t4 values(2,null);
insert into t4 (id) values(3);//默认值生效
检查约束 check
- 语法支持但是没有效果
caeate table t5 (id int,age check(age>10);
insert into t5 values(1,5);
外键约束
- 外键约束作用:为了保证两个表直之间的关系正确建立
1.插入数据时外键值可以为null,可以重复,但是不能是另外一张表不存在的数据
2.被依赖的表不能被先删除
3.被依赖的数据不能先删除 - 如何使用外键:
1.创建部门表
create table dept(id int primary key auto_increment,name varchar(10));
2.创建员工表
create table emp(id int primary key auto_increment,name varchar(10),deptid int, constraint fk_dept foreign key(deptid) references dept(id));
- 介绍:
constraint 约束名称 foreign key(外键字段名)references 表名(字段名); - 测试:
insert into dept values(null,'神仙'),(null,'妖怪');
insert into emp values(null,'悟空',1);//成功
insert into emp values(null,'八戒',1);//成功
insert into emp values(null,'超人',3)//失败 没有3
drop from dept where id=2;//成功
delete from dept where id=1;//失败
索引
什么是索引:
索引是数据库中提高查询效率的技术,类似于字典的目录
为什么使用索引:
如果不适用索引数据会零散的保存在每一个磁盘块当中,查询数据时需要挨个的遍历每一个磁盘块找数据,如果数据量超级大,遍历每一个磁盘块是件非常耗时的事情,添加索引后,会将磁盘块以树状结构进行保存,查询数据时会有目的性的访问部分磁盘块,因为访问的磁盘块数量降低 所以能够起到提高查询效率的作用。
索引是越多越好吗?
不是,因为索引会占磁盘空间,通过某个字段创建的索引可能永远用不上,则这个索引完全没有存在的意义,只需要对查询时频繁使用的字段创建索引
有索引就一定好吗?
不一定 如果数据量小使用索引反而会降低查询效率
索引的分类
1.聚集索引(聚簇(cu)索引):通过主键创建的索引为聚集索引,添加了主键约束的表会自动添加聚集索引,聚集索引的树状结构中保存了数据
2.非聚集索引:通过非主键字段创建的索引叫做非聚集索引,树状结构中只保存了数据所在磁盘块的地址并没有数据。
导入数据:
- windows电脑 把文件放到任意盘下: 以d盘为例
source d:/item)backup.sql
- Linux系统
/home/soft01/桌面/item_backup.sql;
- 测试:
1.show tables;
看是否有item2这张表
2.select count(*) from item2;
看是否有172万条数据
3.select * from item2 where title='100';
//看一下耗时 1.56秒
创建索引的格式:
create index 索引名 on 表明(字段名[(字符长度)]);
create index i_item_title on item2(title);
-创建完后继续执行
select * from item2 where title='100';
//看一下耗时 2.66s
查看索引:
show index from item2;
删除索引
drop index 索引名 on 表名;
drop index i_item_title on item2;
复合索引
通过多个字段创建的索引称为复合索引
-格式:`create index 索引名 on 表名(字段1,字段2);`
频繁使用多个字段进行数据查询时为了提高查询效率可以创建复合索引
select * from item2 where title='100' and price<100;
create index i_item2_title_price on item2(title,price);
总结:
- 1.索引是用于提高查询效率的技术,类似目录
- 2.索引会占用磁盘空间不是越多越好
- 3.如果数据量小的话 添加索引会降低查询效率
- 4.尽量不要在频繁改动的表上改动索引
事物
- 数据库中执行SQL语句的最小工作单元,保证事物中的多条SQL全部成功或全部失败
事物的ACID特性:
- 1.
Atomicity
: 原子性,最小不可拆分 保证全部成功或全部失败 - 2.
Consistency
:一致性,从一个一致状态到另外一个一致状态 - 3.
Isolation
:隔离性,多个事物间互相隔离互不影响 - 4.
Durability
:持久性,事物执提交后 数据持久保存到数据库文件中
事物相关指令:
查看自动提交状态:
show variables like '%ayticinnut%';
提交:
commit;
回滚:
rollback;
保存回滚点:
savepoint s1;
回滚到指定回滚点:
rollback to s1;
group_concat(条件名) 分组连接函数
- 1.查询员工表中 每个部门的所有员工工资
select deptno,group_concat(sal) from emp group by deptno;
- 2.查询员工表中每个部门的员工姓名和对应的工资 要求显示到一条数据中
select deptno,group_concat(ename,':',sal) from emp group by deptno;
面试题分析:
有个学生表student (id,name,subject,socre)
保存一下数据 :
张三 语文 66 , 张三 数学 77 , 张三 英语 55 , 张三 体育 77
李四 语文 59 , 李四 数学 88 , 李四 英语 78 ,李四 体育 95
王五 语文 75 , 王五 数学 54 , 王五 英语 98 , 王五 体育 88
代码
create table student(id int primary key auto_increment,name varchar(10),subject varchar(10),socre int);
insert into student values(null,'张三','语文',66),(null,'张三','数学',77),(null,'张三','英语',55),(null,'张三','体育',77);
insert into student values(null,'李四','语文',59),(null,'李四','数学',54),(null,'李四','英语',78),(null,'李四','体育',95);
insert into student values(null,'王五','语文',75),(null,'王五','数学',54),(null,'王五','英语',98),(null,'王五','体育',88);
- 1.查询每个人的平均分 从大到小 排序
select name,avg(socre) from student group by name order by avg(socre) desc ;
- 2.每个人的姓名 科目 成绩 一行显示出来
select name,group_concat(subject,':',socre) from student group by name;
- 3.查询每个人的最高分和最低分
select name,max(socre),min(socre) from student group by name;
- 4.查询每个人不及格的科目以及分数和不及格的科目数量
select name,subject,group_concat(socre),count(subject) from student where socre<60 group by name;
JDBC
—— ——————————— ————
| 页面 | | webServer Java业务逻辑 | | 数据存储 |
—— ——————————— ————
数据库连接需要在pom.xml
后面粘贴这一串代码
<!-- dependency -->
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
</dependencies>
JDBC概念
JDBC:Java DataBase Connectivity,
java数据库连接 实际上jdbc是Java中的一套和和数据库进行叫苦的api
(application program interface 应用程序编程接口)- 为什么使用JDBC:因为Java程序员需要连接多种数据库 为了避免每一种数据库都学习一套新的api,Sun公司提出了JDBC的接口,各个数据库的厂商根据此接口写实现类(驱动) ,这样 Java程序员只需要掌握JDBC接口的调用即可访问任何数据库。
如何使用JDBC连接MySQL数据库
- 1.创建Maven工程
- 2.登陆maven私服的网站
maven.tedu.cn
外网maven.aliyun.com
首页搜索MySQL 找到 5.1.6版本 把坐标复制到pom.xml
中 - 3.创建Demo01.java类中
public static void main(String[] args) throws ClassNotFoundException, SQLException{
//.注册驱动
/*寻找地址: maven Dependencies -奶瓶下 第一个 com.mysql.jdbc-Driver.class-
* 找到com.mysql.jdbc.Driver复制-粘贴到Class.forName("com.mysql.jdbc.Driver");*/
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3","root", "mother");
//3创建SQL执行对象
Statement stat = conn.createStatement();
//4.执行 SQL
String sql = "create table if not exists jdbc"+"(id int,name varchar(10))";//加上if not exists 重复创建不会报错
stat.execute(sql);
System.out.println("创建完成");
//5.关闭资源
stat.close();
conn.close();
}
JUnit Test 单元测试
- 在无参无返回值的方法上面添加
@Test
注解,通过右键 run as 执行 绿色代表执行成功,红色执行失败
执行SQL的方法
execute();
此方法可以执行任意的SQL 但是推荐执行DDL(数据定义语言create drop alter truncate) 此方法返回值为boolean值 返回值代表的是是否右结果集(只有查询语句有结果集);executeUpdate();
增删改查全部使用此方法 返回值为int 表示生效的行数executeQuery();
此方法执行查询操作 返回ResultSet 通过while循环遍历
自定义模块
//执行查询 得到的结果封装在了resultset中
ResultSet rs = stat.executeQuery(sql);
//遍历结果集
while(rs.next()) {
int empno = rs.getInt("empno");
String name = rs.getString("ename");
double sal = rs.getDouble("sal");
System.out.println(empno+name+sal);
}
- 从ResultSet中获取数据的两种方式:
- 通过表字段的名称获取
- 通过结果中字段的位置获取 (以本次查询的字段顺序为准,并非表字段的顺序)
自定义模板代码
window->preferense->java->editor->templates->new
数据库连接池 DBCP
- 为什么要用连接池:如果没有连接池,一万次请求会对应一万次和数据库服务器的连接和断开连接,使用连接池之后可以将连接池中的连接复用,从而提高执行效率
PerparedStatement预加载的SQL执行对象
- 好处:
1.代码更直观,简介
2.可以避免SQL注入,因为在预编译时已经把sql逻辑固定锁死,不会被之后替换进去的值改变原有逻辑
批量操作 batch
因为每次sql的执行都需要和数据库服务器进行数据传输,如果执行的sql太多每次和数据库进行交互浪费资源执行效率低,使用批量操作可以把多条SQL语句合并到一次交互中,这样可以提高执行效率。
//请输入用户名 libai
//请输入密码 admin
//登陆成功/登陆失败
数据库创建:
create table user(id int primary key auto_increment,username varchar(10),password varchar(10));
insert into user values(null,'libai','admin'),(null,'liubei','123456');
eclipse:
public static void main(String[] args){
Scanner scanner = new Scanner(System.in);
System.out.println("请输入用户名");
String username = scanner.nextLine();
System.out.println("请输入密码");
String password = scanner.nextLine();
boolean b = login(username,password);
if(b){
System.out.println("登陆成功");
}else{
System.out.println("登陆失败");
}
}
private static boolean login(String username, String password) {
String sql = "select count(*) from user " + "where username=? and password=?";
System.out.println(sql);
Connection conn = null;
PreparedStatement stat = null;
ResultSet rs = null;
try {
conn = DBUtils.getConn();
stat = conn.prepareStatement(sql);
stat.setString(1, username);
stat.setString(2, password);
rs = stat.executeQuery();
while(rs.next()){
//得到查询的数量
int count = rs.getInt(1);
if(count>0){//登陆成功
return true;
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
DBUtils.close(conn, stat, rs);
}
return false;
}
}
事物
- 1.关闭自动提交
conn.setAutoCommit(false/true);
- 2.提交
conn.commit();
- 3.回滚
conn.rollback();
- 案例
public static void main(String[] args){
// create table person (id int,name varchar(10),money int);
// insert into person values(1,'超人',500),(2,'钢铁侠',5000);
String sql1 = "update person set money=money+2000 where id=1";
String sql2 = "update person set money=money-2000 where id=2";
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
try {
conn = DBUtils.getConn();
stat = conn.createStatement();
//关闭自动提交
conn.setAutoCommit(false);
//让超人+2000
stat.executeUpdate(sql1);
//让钢铁侠-2000
stat.executeUpdate(sql2);
//查询钢铁侠生于的钱是否>=0;
rs = stat.executeQuery("select money from person where id=2");
while(rs.next()){
int money = rs.getInt("money");
if(money>=0){
//提交
conn.commit();
System.out.println("转账成功");
}else{
conn.rollback();//回转
System.out.println("钢铁侠余额不足");
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
DBUtils.close(conn, stat, rs);
}
}
——————————————————————————————————
回顾总结
数据库相关SQL
- 查询所有
show databases;
- 创建
create database db1 character set utf8/gbk;
- 查看详情
show create database db1;
- 删除
drop database db1;
- 使用
use db1;
表相关SQL
- 创建表
create table t1(id int,name varchar(10)) engine=myisam/innodb charset=utf8/gbk;
- 查看所有
show tables;
- 查看详情
show create table t1;
- 删除
drop table t1;
- 查看字段
desc t1;
- 修改表名
rename table t1 to t2;
- 修改引擎字符集
alter table t1 engine=myisam/innodb charset=utf8/gbk;
- 添加字段
alter table t1 add age int;
- 删除字段
alter table t1 drop age;
- 修改字段名称和类型
alter table t1 change age xxx 类型;
- 修改字段类型和位置
alter table t1 modify age 类型 first/after xxx;
数据相关:
- 插入数据
insert into t1 (字段名1,字段名2) values(值1,值2),(值1,值2),(值1,值2);
- 查询数据
select name,age from emp where id<10;
- 修改数据
update t1 set age=18 where id=10;
- 删除数据
delete from t1 where id<5;
- 主键约束: 唯一且非空
primary key
- 自增:
auto_increment
只增不减 从历史最大值基础+1 - 注释
comment
- ’ 和 `
- 数据冗余: 重复数据 拆分表解决
- 事务:数据库中执行SQL语句的最小工作单元 可以保证事务中的多条SQL语句全部成功或全部失败
SQL分类:
DDL
: 数据定义语言 包括 create alter drop truncate 不支持事务DML
:数据操作语言 包括 insert update delete select(DQL) 支持事务
-DQL
:数据查询语言 包括 selectTCL
:事务控制语言 包括:commit rollback savepoint rollback to。。
-DCL
:数据控制语言 用于分配用户权限
数据类型
- 整数:
int(m)
bigint (m)
代表显示长度 需要结合zerofill使用 - 浮点数:
double(m,d)
m代表总长度 d小数长度 decimal(m,d) - 字符串:
char
固定长度 最大255 执行效率高 varchar可变长度 最大65535 超过255建议使用text text可变长度 最大65535 - 日期:
date
年月日 time时分秒 datetime 默认值null 最大 9999-12-31timestamp
默认当前时间 最大 2038-1-19
30.is null
和is not null
- 别名
- 去重
distinct
- 比较运算符
> < >= <= = !=和<>
and
和or
in
36.between x and y
包含x和ylike
_单个未知 %代表0或多个未知- 排序
order by
字段名 desc,字段名
39.limit
跳过的条数,每页条数 concat(s1,s2)
s1s2- 聚合:求和sum() 平均值avg() 最大值max() 最小值min() 统计数量count(*)
- 日期相关:
now()
curdate()
curtime()
date(now())
time(now())
extract(year/month/day/hour/minute/second from now()) date_format(时间,‘格式’) 格式: %YymcdHhis str_to_date(‘非标准时间’,‘格式’) - ifnull(x,y)
- 字符串相关:char_length() instr() insert() trim() left() right() substring() upper() lower() replace() repeat() reverse()
- 数学相关: floor() round() truncate() rand()
- 分组查询: group by 字段名,字段名
- having后面写聚合函数的条件 where后面写普通字段的条件
- 子查询(嵌套查询) 可以嵌套n层 可以写在 where和having后面做查询条件的值 写在from后面当成虚拟的表 写在创建表的时候 create table 表名 as (子查询);
- 关联查询:同时查询多个表的数据,
- 关联查询的查询方式: 等值连接和内连接、外连接
- 当查询的数据为两张表的交集部分数据时用等值或内连接(推荐)
- select * from A,B where A.x=B.x and A.age=18;
- select * from A join B on A.x=B.x where A.age=18;
- 当查询的数据为某一张表的全部数据和另外一张表的交集数据时使用外连接
-
- select * from A left/right join B on A.x=B.x where A.age=18;
- 笛卡尔积:关联查询不写关联关系 会得到两张表的乘积 称为笛卡尔积
- 一对一: 在从表中添加外键指向主表的主键
- 一对多: 在多的一端 添加外键 指向另外一张表的主键
- 多对多: 通过第三张关系表建立关系
- 自关联: 自己的外键指向自己表的主键称为自关联,当需要保存上级关系时使用自关联
- 权限管理案例:用户表 角色表 权限表 用户角色关系表 角色权限关系表