一:为什么要学习数据库:
之前的操作会将数据存储在文档中,对于修改删除等操作来说,比较繁琐查询效率也较低,
另外,数据量很大的情况下,不肯能长期储存在稳健中,而数据库是按照数据机构来组织、
存储和管理数据的仓库,能为多个用户提供共享,各程序之间彼此独立的数据集合,
简单来说可以看成数据仓库,用户可以对文件中的数据进行新增,截取,更新,删除等操作。
二:数据库的相关概念
DBMS:数据库管理系统(mysql,orcal,sqlserver...)
DB:database,数据库
SQL:structure query language结构化查询语言
三:数据库存储数据的特点:
1.将数据存放在表中,表放在库里
2.一个数据库中可以有非常多的表,每个表都有名字用来标识自己,表名具有唯一性
3.表具有自己的特性,这些特性定义了数据在表中的方式以及结构
4.表由列组成,称为字段,所有表是由一个或多个字段组成的
5.表中的数据按行存储
四:初始mysql
1.mysql产品介绍
关系型数据库:包括相互联系的数据集合,将所有数据关系以数据库表的形式加以表示并将数据存储在表格中
体积小,速度快,总体拥有成本低,开源的(发展会比较稳健,免费)
2.mysql产品的安装
服务端:处理具体数据的维护,保存磁盘
客户端:执行新增,删除,修改,查询
DOS窗口是数据库的客户端之一
windows+r 输入cmd 输入mysql -uroot -proot 回车
作业:安装mysql数据库,成功打开dos窗口
3.MySQL服务的登录和退出:
登录:mysql -uroot -proot
退出:exit/quite;
4.MySQL服务器的启动和停止:
启动:net start MySQL
停止:net stop MySQL
5.MySQL的常见命令和语法规范:
SQL:结构化查询语言,是一种特殊的编程语言,用来存储以及查询更新和管理数据库系统
分类:
DDL:数据定义语言,用来定义数据库对象(库/表/列),负责数据结构定义
常用create\alter\drop
DML:数据操作语言,用来定义数据库记录(数据),数据增删改的操作
常用select\insert\update\delete
DCL:数据控制语言,用来定义访问权限和安全级别
访问权限grant或者revoke取消授权
DQL:数据查询语言,用来查询记录(数据)
select数据检索语句
命令:1.创建数据库:create database 库名 character set utf8;
2.展示数据库:show databases;
3.选择使用数据库:use 数据库名;
4.展示数据库里的所有表:show tables;
5.创建了一个表:字段,字段的数据类型
create table stu(
-> stuno int(6),-------->(字段名1 数据类型(字段约束条件),)
-> name varchar(8),
-> score varchar(5)
-> );
6.查询表结构desc stu;
7.插入语句:insert into emp values(001,'30000','Lisa');
8.数据检索语句:select * from emp(表名);
9.查看数据库编码:show variables like 'char%';
10.查看数据库版本:select version();
11.删除表(一个或多个):DROP TABLE stu; DROP TABLE [IF EXISTS] stu,emp;
6.Mysql中的数据类型:
数值类型:
int普通整数(4字节),double双精度浮点数(8字节),decimal严格的定点数值
字符型类型:
varchar可变长度字符串,char固定长度字符串,enum枚举类型(1或2个字节)
时间\日期类型:
year年YYYY date年月日YYYY-MM-DD Time时分秒HH:MM:SS
datatime8字节(可以存入一个固定时间,YYYY-MM-DD HH:MM:SS)
timestamp4字节(本身存储的数据是从1970-1-1----2038的所有时间数据,可以自动更新当前时间)
7.完整性约束:
1.主键约束:
表中由一列或者多列的组合,要求主键字段数据的唯一性,并且不能为空
单字段约束:
(1)在定义某一字段的同时定义主键
字段名 数据类型(字段约束条件) primary key;
(2)在定义完字段后定义主键:
primary key(字段名);
多字段约束:
primary key(字段名1,字段名2...)
2.主键自增约束:
每次插入新的信息时,系统会自动递增生成字段的主键值
在一个表上自动递增的数据只有一个
字段名 数据类型(字段约束条件) primary key auto_increment;
3.外键约束
外键就是在不同的表之间建立连接,一个表可以有一个或多个外键
外键不一定是本表的主键,但对应的是另外一个表的主键
与外键关联的字段不允许被删除,如果必须删除首先要将外键撤销
foreing key(字段名) reference 主表名(主键字段);
4.非空约束:
字段值不能为空
字段名 数据类型 not null;
5.唯一性约束:
对某字段使用此约束,允许为空,但是只出现一个空值
字段名 数据类型 unique;
作业:1.新建课程表course,插入三个字段:cno\cname\tno
2.新建成绩表score,插入三个字段:sno\cno\tno\degree
主键:sno+cno
五:DQL语言的学习:select
1.基础查询
(1)查询所有表信息
select * from studen
(2)查询相关字段信息
SELECT sname,ssex,class(字段1,2,3...)FROM student;
特点:通过这样的查询可以查询到表中所有字段,常量,函数,表达式
结果是一个虚拟表格
(3)查询常量值:SELECT 10985(常量值)
(4)查询表达式:SELECT 100%98(表达式);
注意事项:SELECT 100+98;操作都是数值类型的话做加法运算
SELECT '123'+98;其中一个数是字符串类型,字符串转换成功则做加法运算;
字符串转换不成功则转换成0继续做加法运算
SELECT NULL+10;只要其中一个加号是null,则结果肯定是null
(5)去重查询:查询某字段中去除重复信息后数据(DISTINCT)
SELECT DISTINCT class FROM student;
2.条件查询
语法:SELECT 查询列表(字段) FROM 表名 WHERE 筛选条件;
条件判断符:
=\>\<\!=\<=\>=
逻辑运算符:
&&与(两边为真为真,只要有一个为假,结果为假),||或(两边为假就为假,只要有一边为真结果就为真), !非
AND 并且
OR 或者
not 相反
(1)查询表中成绩在70-90之间所有数据
SELECT * FROM score WHERE degree BETWEEN 70 AND 90;
(2)查询score表成绩是85,92,90的数据
SELECT * FROM score WHERE degree=85 OR degree=92 OR degree=90;
select * from score where degree in(85,92,95);
(3)查询student表中性别为女以及班名为15038的所有数据
SELECT * FROM student WHERE ssex='女' OR class='15038';
(4)以degree降序(DESC)查询sccore表中的所有数据(升序为ASC)
SELECT * FROM score ORDER BY degree DESC;
(5)查询部门编号不等于90号的员工名和部门编号
SELECT last_name department_id FROM employees WHERE department_id!=90;
(6)查询工资在10000到2000之间的员工姓名、工资以及奖金
SELECT first_name,salary,commission_pct FROM employees WHERE salary>=10000 AND salary <=20000;
(7)查询部门编号不是90到110之间的,或者工资高于15000的员工信息
SELECT * FROM employees WHERE NOT (department_id >= 90 AND department_id <= 110) OR salary >= 15000;
3.模糊查询
3.1 like
特点:一般情况下和通配符搭配使用
%任意多个字符,包含0个字符
_任意单个字符
(1)查询员工姓名中包含字符a的员工信息
SELECT * FROM employees WHERE last_name LIKE '%a%';
(2)查询员工名中第三个字符为e,第五个字符为a的员工名和工资
SELECT last_name,salary FROM employees WHERE last_name LIKE '__e_a%';
(3)查询员工名中第二个字符为_的员工名(ESCAPE转义名词,用下划线表示一个字符的通配符,如果需要查询某个字段中的记录,我们需要定义一个带字符,使用完毕后escape排除这个字符,也就是自定义将$转义成_)
SELECT last_name FROM employees WHERE last_name LIKE '_$_%' ESCAPE '$';
3.2 BETWEEN...AND...位于两值之间
特点:1.提高语句的简洁度
2.包含临界值
3.这两个临界值不能调换位置
3.3 IN(set)包含,判断某个字段的值是否属于In列表中的某一项
特点:1.提高语句简洁度
2.in列表的数据类型必须一致
3.in列表的值不支持通配符
(1)查询job_id是IT_PROG、AD_PRES的员工姓名和job_id
SELECT job_id,last_name FROM employees WHERE job_id IN('IT_PROG',' AD_PRES');
(2)查询employee_id是100,102,103的员工
SELECT * FROM employees WHERE employee_id in(100,102,103);
3.4 is null 为空is not null 不为空
注意:=和<>都不能判断判断NULL
(1)查询commission_pct为空的员工名字和commission_pct
SELECT commission_pct,last_name FROM employees WHERE commission_pct IS NULL;
(2)安全等于表达符号<=>
查询没有奖金的员工名字和奖金
SELECT commission_pct,last_name FROM employees WHERE commission_pct<=>NULL;
3.5 起别名:
特点:1.便于理解
2.如果需要使用的字段有重名的现象,使用别名就可以区分开来
使用关键字AS或者空格
(1)查询员工姓名,并将姓名重命名为'姓名'
SELECT last_name AS 姓,first_name AS 名 FROM employees;
(2)查询salary,显示结果为‘output’
SELECT salary AS 'output' FROM employees;
4.排序查询:
语法:SELECT * FROM 表名 ORDER BY 排序的字段或者表达式 DESC;
特点:1.DESC表示降序,ASC表示升序
2.oeder by是可以支持单个字段、别名、表达式、函数
3.写在查询语句的最后,除了limit字句
(1)查询员工信息并且按照工资从高到低排列
SELECT * FROM employees ORDER BY salary DESC;
(2)查询部门编号>=90的员工信息并且按照员工编号降序
SELECT * FROM employees WHERE department_id>=90 ORDER BY employee_id DESC;
(3)查询员工信息并且按照年薪降序排序
SELECT * FROM employees ORDER BY salary*12*(1IFNULL(commission_pct,0)) DESC;
(4)起别名(3)---表达式
SELECT *,salary*12*(1+IFNULL(commission_pct,0))AS 年薪 FROM employees ORDER BY salary*12*(1+IFNULL(commission_pct,0)) DESC;
(5)查询员工名,并且按照名字长度排序---函数
SELECT LENGTH(last_name),last_name FROM employees ORDER BY LENGTH(last_name) DESC;
(6)查询员工信息,先按工资降序再按员工编号升序
SELECT * FROM employees ORDER BY salary DESC,employee_id ASC;
(7)查询员工的姓名和部门和年薪,按照年薪降序,再按照员工名升序
SELECT
department_id,
last_name,
salary * 12 * (1 + IFNULL(commission_pct, 0))
FROM
employees
ORDER BY
salary * 12 * (1 + IFNULL(commission_pct, 0)) DESC,
last_name ASC;
(8)查询邮箱中包含e的员工信息,先按邮箱的字节数降序,再按部门编号升序*/
SELECT * FROM employees WHERE email LIKE '%e%' ORDER BY LENGTH(email) DESC,department_id ASC;
5.常见函数
在java里面将一组逻辑语言封装在方法体中
优点:1.隐藏代码运行细节
2.提高代码的重用性
在数据库中调用:select 函数名 (实参列表)
特点:1.函数名
2.函数功能
5.1单行函数(一个函数返回一个值)
字符函数:
LENGTH\content\IFNULL...
(1)LENGTH()获取参数值的字节个数
SELECT LENGTH('Ellen');
(2)CONCAT(,,)拼接字符串
SELECT CONCAT(last_name,'_',first_name) AS 姓名 FROM employees;
(3)UPPER(),LOWER()转换大小写
SELECT UPPER('dwt');
SELECT LOWER('DWT');
(4)将员工表里的姓大写,名小写,然后拼接
SELECT CONCAT(UPPER(last_name),LOWER(first_name)) AS 姓名 FROM employees;
(5)SUBSTR()截取数据
SELECT SUBSTR('今晚我想吃大盘鸡',7) AS 结果;
SELECT SUBSTR('今晚我想吃大盘鸡',5,4) AS 结果2;
(6)姓名中首字符大写,其他字符小写然后用_拼接,显示为结果3
SELECT CONCAT(UPPER(SUBSTR(last_name,1,1)),'_'
LOWER(SUBSTR(Last_name,2))) AS 结果3 FROM employees;
(7)instr()通过子串的下标索引获取
SELECT INSTR('路飞一行人踏上了征程','征程') AS 结果;
(8)TRIM()截取
SELECT LENGTH(TRIM(' 乔巴 ' ));/*6*/
SELECT TRIM('a' FROM 'aaaaaa乌aaaa索普aaaaaaaaaaaaaa') AS 结果;/*乌aaaa索普*/
SELECT TRIM('aa' FROM 'aaaaaaa乌aaaa索普aaaaaaaaaaaaaa')AS 结果2;/*乌aaaa索普*/
(9)LPAD()用指定的字符去实现左填充指定长度
SELECT LPAD('山治',10,'*');/*(********山治)*/
(10)RPAD()用指定的字符去实现右填充指定长度
SELECT RPAD('山治',10,'*');/*(山治********)*/
(11)REPLACE()替换
SELECT REPLACE('我最近爱上了学习','爱上了','酷爱') AS 结果;/*我最近酷爱学习*/
SELECT REPLACE('我最近爱上了爱上了学习','爱上了','酷爱') AS 结果1;/*我最近酷爱酷爱学习*/
数学函数:
(1)ROUND()四舍五入
SELECT ROUND(1.55);/*2*/
SELECT ROUND(-1.55);/*-2*/
(2)CEIL()向上取整,返回值大于等于该参数的最小整数
SELECT CEIL(0.01);/*1*/
SELECT CEIL(-1.12);/*-1*/
(3)FLOOR()向下取整,返回值小于等于该参数的最大整数
SELECT FLOOR(9.99);/*9*/
SELECT FLOOR(-9.99);/*-10*/
(4)TRUNCATE()
SELECT TRUNCATE(1.65,1);/*1.6*/
SELECT TRUNCATE(1.699999,2);/*1.69*/
(5)MOD()取余*/
SELECT MOD(10,-3);/*1*/
SELECT MOD(-10,3);/*-1*/
日期函数:
(1)NOW()当前日期+时间
SELECT NOW();
(2)CURDATE()当前日期
SELECT CURDATE();
(3)CURTIME()当前时间
SELECT CURTIME();
(4)获取指定年份
SELECT YEAR('2020-05-05');
(5)查询员工表里入职时间的所有年份*/
SELECT YEAR(hiredate) AS 年份 FROM employees;
(6)获取指定月份
SELECT MONTH(NOW());
(7)获取月份名称
SELECT MONTHNAME(NOW());
(8)STR_TO_DATE()将字符通过指定的格式转换成日期
SELECT STR_TO_DATE('2000-12-8','%Y-%m-%d')AS 结果;
(9)查询入职日期是1992-4-3的员工
SELECT * FROM employees WHERE hiredate=STR_TO_DATE('1992-4-3','%Y-%m-%d');
(10)DATE_FORMAT()将日期转换成字符*/
SELECT DATE_FORMAT(NOW(),'%y年%m月%d日') 结果;
(11)查询有奖金的员工名和入职日期(xx年xx月xx日)*/
SELECT last_name,DATE_FORMAT(hiredate,'%m月%d日%y年') FROM employees WHERE commission_pct IS NOT NULL;
其他函数:
SELECT VERSION();
SELECT DATABASE();
SELECT USER();
流程控制函数
(1)IF函数:if else 的效果
SELECT IF('10>5','大','小');
SELECT last_name,commission_pct,
IF(commission_pct
IS NULL,'没奖金','有奖金')
FROM employees;
重点 (2)case函数:switch case函数
switch(变量或者表达式){
case1 常量1:语句1;break;
case2
...
default:语句 n;break;}
mysql里:
case要判断的字段或表达式
when 常量1 then 要显示的值(语句1)
when 常量2 then 要显示的值(语句2)
...
end
查询员工的工资,要求:
部门号是10的,显示的工资是1.1倍
部门号是40的,显示的工资是1.2倍
部门号是70的,显示的工资是1.3倍
其他的部门,显示的工资是原工资
SELECT salary AS 原工资,department_id,
CASE department_id
WHEN 10 THEN 1.1*salary
WHEN 40 THEN 1.2*salary
WHEN 70 THEN 1.3*salary
ELSE salary
END AS 新的工资
FROM employees;
难点 (3)查询员工的工资:
如果工资大于20000,显示A
如果工资大于15000,显示B
如果工资大于10000,显示C
其他的显示为D
SELECT salary,
CASE
WHEN salary>=20000 THEN 'A'
WHEN salary>=15000 THEN 'B'
WHEN salary>=10000 THEN 'C'
ELSE 'D'
END AS 级别
FROM employees;
5.2分组函数---统计函数、聚合函数、组函数
分类:
sum求和、avg平均数、max最大值、min最小值、count计算个数
特点:
1.sum,avg一般用于处理数值型
2.max,min,count可以处理任何类型
3.所有分组函数都忽略null值
4.可以和DISTINCT去重搭配使用
5.count
(1)SELECT SUM(salary) AS 工资总和 FROM employees;
(2)SELECT AVG(salary) AS 工资平均 FROM employees;
(3)SELECT MAX(salary) AS 最大值 FROM employees;
(4)SELECT MIN(salary) AS 最小值 FROM employees;
(5)SELECT COUNT(salary) AS 字段总和 FROM employees;
(6)SELECT SUM(salary) 和,AVG(salary) 平均值,MAX(salary) 最大,MIN(salary)最小,COUNT(salary)个数总和 FROM employees;
6.分组查询
语法:select 查询列表 from 表名 where 筛选条件 group by 分组字段;
注意:1.查询列表必须特殊,要求是分组函数和GROUP BY 后出现的字段
2.
针对的表 位置 关键字
重点 分组前筛选: 原始表 group by前 WHERE
分组后帅选: group by的结果集 group by后 Having
WHERE和Having的区别:
1.分组前筛选用where
2.分组后筛选用Having
3.WHERE不能使用列别名和聚合函数(sum,avg,count)
(1)查询各个job_id的员工工资的最大值,最小值,平均值,总和,并按照job_id升序
SELECT MAX(salary),MIN(salary),AVG(salary),SUM(salary),job_id FROM employees GROUP BY job_id ORDER BY job_id ASC;
(2)查询各个管理者手下的员工最低工资,其中最低工资不能低于6000,
没有管理者的员工不计算在内
SELECT
MIN(salary),manager_id
FROM
employees
WHERE
manager_id IS NOT NULL
AND salary >= 6000
GROUP BY
manager_id;
(3)查询每个部门的员工个数
SELECT COUNT(department_id),department_id FROM employees GROUP BY department_id;
(4)查询每个工种的员工平均工资
SELECT AVG(salary),job_id FROM employees GROUP BY job_id;
(5)查询每个位置的部门个数
SELECT COUNT(department_id),location_id FROM departments GROUP BY location_id;
(6)查询邮箱中包含a字符的,每个部门的最高工资
SELECT MAX(salary),email,department_id FROM employees WHERE email LIKE '%a%' GROUP BY department_id;
(7)查询有奖金的每个领导手下员工的平均工资
SELECT AVG(salary),manager_id FROM employees WHERE commission_pct IS NOT NULL GROUP BY manager_id;
难点 (8)查询哪个部门的员工个数大于5
1.查询 每个部门的所有员工个数
2.筛选出大于5的
SELECT COUNT(*) AS 员工个数,department_id FROM employees GROUP BY department_id HAVING COUNT(*)>5;
(9)查询每个工种有奖金的员工的最高工资>12000的工种编号和最高工资
1.查询每个工种有奖金的员工的工种编号和最高工资
2.在此基础上筛选出工资>12000
SELECT MAX(salary),job_id FROM employees WHERE commission_pct is NOT NULL GROUP BY job_id HAVING MAX(salary)>12000;
(10)查询管理者编号>102的每个管理者手下员工最低工资大于5000的管理者编号和最低工资
1.查询管理者编号>102的每个管理者编号和最低工资
2.在此基础上筛选管理者手下员工最低工资大于5000
SELECT manager_id,MIN(salary) FROM employees WHERE manager_id>102 GROUP BY manager_id HAVING MIN(salary)>5000;
(11)查询每个工种有奖金的员工的最高工资>6000的工种编号和最高工资,
按最高工资降序排序
*注意:排序写在分组之后*
SELECT
job_id,
MAX(salary)
FROM
employees
WHERE
commission_pct IS NOT NULL
GROUP BY
job_id
HAVING
MAX(salary)>6000
ORDER BY
MAX(salary) DESC;
(12)*多个字段分组查询*
查询每个工种每个部门的最低工资,按最低工资降序排序
SELECT
job_id,
department_id,
MIN(salary)
FROM
employees
GROUP BY
job_id,department_id
ORDER BY
MIN(salary) DESC;
作业:1.思考分组函数是否能放在WHERE之后
sql语句中,where必须放在group之前,因为分组查询是根据WHERE条件查询出来的数据作为结果的,也就是说,分组必须对WHERE选择后的结果进行分组,不能直接对原表进行分 组
2.练习之前内容
7.连接查询
笛卡尔乘积现象:表1有n行,表2有m行,结果是m*n行
发生原因:没有添加有效的连接条件
如何避免:添加有效的连接条件
分类:
1.按照年代区分:
sql192标准:仅仅支持内连接
sql199标准:支持内连接,外连接,交叉连接
2.按照功能区分:
内连接:等值连接
非等值连接
自连接
外连接:右外连接
左外连接
全外连接
交叉连接:
7.1 sql92连接:内连接
等值连接:
1.多表等值连接的结果是多表的交集部分
2.n表连接,至少需要n-1个条件
3.多表的顺序没有要求
4.一般情况下要为表起别名
5.可以搭配前面使用的所有子句使用,比如排序,分组,筛选
非等值连接:不完全是不等值连接,还可以是其他连接(大于,小于或者其他关系)
自连接:相当于等值连接
sql99标准:内连接 inner
外连接:右外连接:right(outer)
左外连接:left(outer)
全外连接:full(outer)
交叉连接:cross
语法:select 查询列表 from 表1 别名 连接类型 表2 别名
on 连接条件
where 筛选条件
group by分组
having 筛选条件语句
order by排序
内连接:Inner(重要!!!)
语法:select 查询列表 from 表1 别名 inner join 表2 别名
on 连接条件;
等值连接
1.添加排序,分组,筛选
2.inner可以省略
3.筛选条件写在where后面,连接条件写在on后面
4.查询内容是多表的交集部分
非等值连接
自连接
外连接:用来查询一个表中又而另外一个表中没有的数据
特点:
1.外连接的查询结果是主表的所有结果,如果从表中有和主表信息匹配的,则会显示匹配的值,如果从表中没有和主表信息匹配的,则会显示null
2.外连接的查询结果=内连接的结果+主表中有而从表中没有的值
3.左外连接:left(outer)左边是主表
右外连接:right(outer)右边是主表
全外连接:full(outer)
4.左外和右外调换两个表的顺序,可以实现同样的效果
交叉连接:cross
特点:九九乘积
总结:sql92标准和sl99标准:
1.ssql99标准支持的连接类型较多
2.可读性高,实现了连接条件和筛选条件的分离
(1)/*sql92标准联表查询*/
查询员工名和对应的部门名
SELECT
last_name,
department_name
FROM
employees AS e,
departments AS d
WHERE
e.department_id=d.department_id;
(2)查询员工名,工种号,工种名
SELECT last_name,e.job_id,job_title
FROM employees AS e,jobs AS j
WHERE e.job_id=j.job_id;
(3)/*进行联表查询的筛选*/
查询有奖金的员工名和部门名
SELECT last_name,department_name,commission_pct
FROM employees AS e,departments as d
WHERE e.department_id=d.department_id AND commission_pct IS NOT null;
(4)查询城市名中第二个字符为o的部门名和城市名*/
SELECT department_name,city
FROM locations l,departments d
WHERE l.location_id=d.location_id AND city LIKE '_o%';
(5)/*可以添加排序*/
查询每个工种的工种名和员工的个数,并且按照员工个数降序排序
SELECT job_title,COUNT(*)
FROM employees AS e,jobs AS j
WHERE e.job_id=j.job_id
GROUP BY job_title
ORDER BY COUNT(*) DESC;
(6)/*可以实现三表连接*/
查询员工名,部门名,所在城市且城市首字母为s
SELECT last_name,department_name,city
FROM employees e,departments d,locations l
WHERE e.department_id=d.department_id
AND d.location_id=l.location_id
AND city LIKE 's%';
难点 (7)/*非等值连接*/
查询员工的工资和工资等级
SELECT salary,grade_level
FROM employees e,job_grades g
WHERE salary BETWEEN g.lowest_sal AND g.highest_sal
难点 (8)/*自连接*/
查询员工的名和上级的名称
SELECT e.employee_id,e.last_name,m.employee_id,m.last_name
FROM employees e,employees m
WHERE e.manager_id=m.employee_id;
(10)/*sql99标准联表查询*/
/*内连接 等值连接*/
查询员工名和部门名
SELECT last_name,department_name
FROM employees e INNER JOIN departments d
ON e.department_id=d.department_id
(11)查询名中包含e的员工名和工种名
SELECT last_name,job_title
FROM employees e INNER JOIN jobs j
ON e.job_id=j.job_id/*联表条件*/
WHERE last_name LIKE '%e%';/*筛选条件*/
(12)查询部门个数>3的城市名和部门个数
每个城市部门个数,筛选大于三个的
SELECT city,COUNT(*)
FROM locations l INNER JOIN departments d
ON l.location_id=d.location_id
GROUP BY city
HAVING COUNT(*)>3;
(13)查询部门的员工个数大于3的部门名和员工个数,并且按照员工个数降序
SELECT COUNT(*),job_title
FROM employees e INNER JOIN jobs j
ON e.job_id=j.job_id
GROUP BY department_id
HAVING COUNT(*)>3;
ORDER BY COUNT(*) DESC;
重点 (14)/*三表联查*/
查询员工名,部门名,工种名并且按照部门名降序
SELECT last_name,department_name,job_title
FROM employees e
INNER JOIN departments d
ON e.department_id=d.department_id
INNER JOIN jobs j
ON e.job_id=j.job_id
ORDER BY department_name DESC;
(14)/*非等值连接*/
查询员工的工资和工资级别
SELECT salary,grade_level
FROM employees e INNER JOIN job_grades g
ON e.salary BETWEEN g.lowest_sal AND g.highest_sal;
(15)查询员工工资级别的个数>20的个数,并且按照工资级别降序排序
SELECT COUNT(*),grade_level
FROM employees e INNER JOIN job_grades g
ON e.salary BETWEEN g.lowest_sal AND g.highest_sal
GROUP BY grade_level
HAVING COUNT(*)>20
ORDER BY grade_level DESC;
难点 (16)/*自连接*/
查询员工的名和上级的名称
SELECT e.last_name,m.last_name
FROM employees e JOIN employees m
ON e.manager_id=m.employee_id;
难点 (17)/*外连接*/
查询男朋友信息不在男生表的女生名(女生表是主表)
SELECT b.name,bo.*
FROM beauty b LEFT JOIN boys bo
ON b.boyfriend_id=bo.id;
(18)查询哪个部门没有员工(部门表是主表)
SELECT d.*,employee_id
FROM departments d LEFT JOIN employees e
ON d.department_id=e.department_id
WHERE employee_id IS NULL;
(19)/*全外连接*/
查询部门信息以及员工信息
SELECT d.*,e.*
FROM departments d FULL JOIN employees e
ON d.department_id=e.department_id;
(20)/*交叉连接*/
SELECT d.*,e.*
FROM departments d CROSS JOIN employees e;
难点8.子查询
含义:出现在其他的查询语句中select语句,又称为内查询语句,(子查询语句的)外部查询语 句称为主程序语句
分类:按照子查询语句出现位置:
select后面
标量子查询
from后面
表子查询
where和Having后面(重要!!!)
标量子查询
列子查询
行子查询
exists后面
表子查询
按照结果集的行列数不同:
标量子查询(结果集只有一行一列)
列子查询(结果集有一列多行)
行子查询(结果集有一行多列)
表子查询(结果集有多行多列)--相关子查询
8.1 where或Having后面(重要!!!)
标量子查询(单行)
列子查询(多行)
行子查询
特点:1.子查询语句放在()里面
2.子查询一啊不能放在条件的右侧
3.标量子查询,一般情况下搭配单行操作符使用(< > >= <= <>)
列子查询,一般情况下搭配多行操作符使用(in any/some all)
in/not in:等于列表中的任意一个
any/some:任一,和子查询返回的某一个值做比较
all:和子查询返回的每一个值作比较
8.2 select后面(仅仅支持标量子查询),不常用
8.3 from后面,表子查询,将子查询结果看成表来用,要求必须起别名
8.4 exists后面,相关子查询
语法:exists(完整查询语句)
结果:1和0
(1)/*where或Having后面(重要) 标量子查询(单行)*/
谁的工资比Abel高?
1.Abel的工资是多少
2.比较谁的工资高于Abel
SELECT *
FROM employees
WHERE salary>(
SELECT salary
FROM employees
WHERE last_name='Abel'
);
(2)查询job_id与141号员工相同,
salary比143号员工多的员工姓名,job_id和工资
SELECT last_name,job_id,salary
FROM employees
WHERE job_id=(
SELECT job_id FROM employees WHERE employee_id=141)
AND salary>(
SELECT salary FROM employees WHERE employee_id=143);
作业:
1.显示所有员工的姓名,部门号和部门名称。
2.查询90号部门员工的job_id和90号部门的location_id
3.选择所有有奖金的员工
4.选择city在Toronto工作的员工
5.查询每个工种、每个部门的部门名、工种名和最低工资
6.查询每个国家下的部门个数大于2的国家编号
7.选择指定员工的姓名,员工号,以及他的管理者的姓名和员工号,结果类似于下面的格式
employees Emp# manager Mgr#
kochhar 101 king 100
重点:(3)/*HAVING后面的标量子查询*/
查询最低工资大于50号部门最低工资的部门和其最低工资
1.查询50号部门的最低工资
2.查询每个部门最低工资
3.大于50号部门
SELECT
MIN(salary),
department_id
FROM
employees
GROUP BY
department_id
HAVING
MIN(salary) > (SELECT MIN(salary) FROM employees WHERE department_id = 50);
(4)/*列子查询*/
查询Location_id是1400或者1700的部门中的所有员工姓名
1.查询Location_id是1400或者1700的部门编号
2.查询员工姓名,要求部门号是第一次查询列表中的某一个
SELECT
last_name
FROM
employees
WHERE
department_id IN (SELECT department_id FROM departments
WHERE location_id IN (1400, 1700));
(5)查询其他工种中比job_id为'IT_PROG'工种任意一个工资低的
员工的员工号、姓名,job_id和salary
SELECT DISTINCT employee_id,last_name,salary,job_id
FROM employees
WHERE
salary <ANY(SELECT salary FROM employees WHERE job_id='IT_PROG') AND job_id<>'IT_PROG';
(6)/*行子查询*/
查询员工编号是最小的并且工资最高的员工信息
1.查询最小的员工编号
2.查询最高工资
3.查询员工信息
SELECT * FROM employees
WHERE(employee_id,salary)=
(SELECT MIN(employee_id),MAX(salary) FROM employees);
(7)/*selsect后面*/
每个部门的员工个数
SELECT d.*,(
SELECT COUNT(*) FROM employees e
WHERE e.department_id=e.department_id
) 个数
FROM departments d;
(8)查询员工号=102的部门名
SELECT(
SELECT department_name FROM departments d
JOIN employees e ON d.department_id=e.department_id
WHERE e.employee_id=102
) 部门名;
(9)/*from后面*/
查询每个部门的平均工资的工资等级
1.查询每个部门的平均工资(子查询出的结果作为一个新表并起别名ag_dep)
2.查询工资等级*/
SELECT ag_dep.*,g.grade_level
FROM (
SELECT AVG(salary) ag,department_id
FROM employees
GROUP BY department_id
) AS ag_dep JOIN job_grades g ON ag_dep.ag BETWEEN lowest_sal AND highest_sal;
(10)/*exists后面*/
SELECT EXISTS(SELECT employee_id FROM employees);/*1*/
SELECT EXISTS(
SELECT employee_id FROM employees
WHERE salary=30000
);/*0*/
9.分页查询
应用场景:当要显示的数据,一页显示不全的情况下就需要sql提交请求
语法:
select 查询列表 from 表名 联表类型(join type)
on 连接条件
where 筛选条件
group by 分组条件
having 筛选条件
order by 排序的字段
limit(offset,size分页关键词)
特点:
1.limit语句放在查询语句的最后
2.公式:limit[offset,size]
offset:要显示条目的起始索引(从0开始)
size:要显示的具体条目个数
要显示的页数page
每页的条目数size
select 查询列表
from 表名
limit 页数,size
limit(page-1)*size,size
(1)/*分页查询*/
查询前五条员工信息
SELECT * FROM employees LIMIT 5;
(2)查询第11条-15条员工信息*/
SELECT * FROM employees LIMIT 10,5;
(3)查询有奖金的员工信息,并且工资较高的前十名显示出来*/
SELECT * FROM employees
WHERE commission_pct IS NOT NULL
ORDER BY salary DESC
LIMIT 10;
作业:
难点1.查询有员工的部门名#EXISTS*/
SELECT
department_name
FROM
departments d
WHERE
EXISTS(
SELECT * FROM employees e
WHERE e.department_id = d.department_id
);
2.查询公司工资最少的员工的last_name,job_id和salary*/
SELECT last_name,job_id,salary
FROM employees
WHERE salary=(SELECT MIN(salary) FROM employees);
10.union联合查询
概念:将多条查询语句的结果集合并成一个结果
语法:
查询语句 1 union 查询语句2 union ...
特点:1.要查询的结果来自于多个表而且多个表之间没有直接的连接关系,但是查询的信息一致
2.联合查询的列数要保持一致
(1)查询部门编号大于90或者邮箱包含a的员工信息
SELECT * FROM employees WHERE department_id>90
union
SELECT * FROM employees WHERE email LIKE '%a%';
难点 (2)查询没有奖金和在us工作的员工信息
SELECT * FROM employees e INNER JOIN departments d
ON e.department_id=d.department_id
INNER JOIN locations l
ON d.location_id=l.location_id
WHERE commission_pct IS NULL
UNION
SELECT * FROM employees e INNER JOIN departments d
ON e.department_id=d.department_id
INNER JOIN locations l
ON d.location_id=l.location_id
WHERE country_id='US';
六.DML语言的学习
1.插入语言语句inserst
语法:
insert into 表名(列名...) values(值...)
注意:1.插入的值的字段必须和值匹配
2.插入的值的类型必须和字段的数据类型一致
3.不可以为null(非空)的列必须插入
可以null的列如何插入数据信息
3.1给出列名并填写null值
3.2列名和值名都不写
4.列的顺序可以进行调换(数值顺序也要跟随列内容的调换)
5.列数和值的个数必须一致
6.可以省略列名,默认所有列,一定要注意插入信息列的顺序和表中的列的顺序一致
语法二:
insert into 表名(列名...)
set 列名=值,列名=值,...
两种写法的区别,第一种插入数据写法支持:
1.支持批量添加数据
2.支持子查询
2.修改语句update
修改表记录(修改表的一部分,不是全部)
1.修改单表的记录
对于单个或者多个列名都可以修改相应的值
语法:
update 表名(1)
set 列名=值,列名=值...(3)
where 筛选条件;(2)
2.修改多表的记录
注意:表必须写别名
语法:
sql92标准:
update 表1 别名,表2 别名
set 列=值...
where 联表条件
and 筛选条件;
sql99标准:
update 表1 别名
inner/left/right 表2 别名
on 联表条件
set 列=值...
where 筛选条件;
3.删除语句delete
1.delete整行删除,一删一行
语法:
1.1单表删除
delete from 表名 where 筛选条件;
1.2多表删除
sql92标准:
delete 别名,别名...
from 表1 别名,表2 别名...
where 联表条件
and 筛选条件;
sql99标准:
delete 别名,别名...
from 表1 别名,表2 别名...
inner/left/right 表3 别名...
on 联表条件
where 筛选条件;
2.truncate整表删除(清空删除)
语法:turncat tables 表名;
4.delete和truncate的区别:
1.delete可以加where筛选条件,truncate可以加
2.turncat删除的效率高一点
3.假如需要删除的表中有自增长列
如果用delete删除后,再插入数据,自增长列的值从断点开始
truncate删除后,再插入数据,自增长列的值从1开始
4.delete删除有返回值,truncat删除没有返回值
5.truncat删除不能回滚,delete删除能回滚
#插入语言
INSERT into beauty(id,name,sex,borndate,phone,photo,boyfriend_id)
VALUE('13','Lisa','女','1997-05-05','17793495062',NULL,2);
SELECT * FROM beauty;
#非空的信息插入
INSERT into beauty(id,name,sex,borndate,phone,boyfriend_id)
VALUE('14','邓文亭','女','1998-12-08','17793495063',2);
#插入信息的顺序
INSERT into beauty(name,sex,id,borndate,phone,photo,boyfriend_id)
VALUE('孙俪','女','15','1987-05-05','17793495064',NULL,2);
#列数和值的个数必须一致
INSERT into beauty(name,sex,id,borndate,phone)
VALUE('关晓彤','女','16','1987-01-01','17793495064');
#省略列名,写入相关值
INSERT into beauty
VALUE('17','丫丫','女','1987-056-05','17793495068',NULL,2);
#插入数据的语法二
INSERT into beauty
SET id=18,name='周扬青',phone='11111111111';
#两种写法的区别
INSERT INTO beauty
VALUES
('19','赵1','女','1998-12-05','145623787',NULL,2)
('20','赵2','女','1998-12-06','145623789',NULL,3);
#支持子查询
INSERT into beauty(id,name,phone)
SELECT 21,'宋茜','10000';
#修改语句update
#单表中种单个字段数据修改
update beauty
set phone='114'
where name LIKE '赵%';
#单表中多个字段数据修改
update boys
set boyName='彭于晏',userCP='1000'
where id=2;
#多表中的修改
#修改张无忌的女朋友的手机号为111111
#先找到张无忌的女朋友,再去修改号码
UPDATE boys bo
INNER JOIN beauty b
ON bo.id=b.boyfriend_id
SET b.phone='1111111'
WHERE bo.boyName='张无忌';
难点#修改没有男朋友的女生的男朋友编号都是2号
UPDATE boys bo
RIGHT JOIN beauty b
ON bo.id=b.boyfriend_id
SET b.boyfriend_id=2
WHERE bo.id is NULL;
#删除
#单表删除
DELETE FROM beauty WHERE name LIKE '宋%';
#多表删除
#删除张无忌的女朋友的信息
DELETE b
FROM boys bo
INNER JOIN beauty b
ON bo.id=b.boyfriend_id
WHERE bo.boyName='张无忌';
#删除黄晓明的信息以及他的女朋友的信息
DELETE b,bo
FROM boys bo
INNER JOIN beauty b
ON bo.id=b.boyfriend_id
WHERE bo.boyName='黄晓明';
#整表删除
TRUNCATE TABLE boys;
七.DDL语言的学习--数据定义语言
创建 create
修改 alter
删除 drop
库和表的管理
1.库的管理
创建 CREATE DATABASE IF NOT EXISTS 库名;
修改
修改库名 RENAME DATABASE 旧库名 to 新库名;
修改库的字符集 ALTER DATABASE 库名 CHARACTER SET utf8;
删除 DROP IF EXISTS database 库名
2.表的管理
创建 create table 表名(列名 列的类型【(长度),约束 】,。。。);
修改
修改表名 ALTER TABLE 旧表名 RENAME TO 新表名;
修改列名 ALTER TABLE 表名 CHANGE COLUMN 旧列名 新列名 数据类型;
修改列的类型 ALTER TABLE 表名 MODIFY COLUMN 列名 数据类型;
添加新列 ALTER TABLE 表名 ADD COLUMN 新列名 数据类型;
删除列 ALTER table 表名 DROP COLUMN 列名;
删除
删除表 DROP TABLE IF EXISTS 表名;
复制
仅仅复制表的结构 CREATE TABLE 表名 LIKE 被复制的表;
只复制表的部分字段(部分列) CREATE TABLE 表名 SELECT 字段 FROM 被复制的表 WHERE 0;
复制表结构和数据 CREATE TABLE 表名 SELECT * FROM 被复制的表;
只复制表的部分数据 CREATE TABLE 表名 SELECT 字段 FROM 被复制的表
WHERE 约束条件;
3.常见数据类型介绍(内容开始部分)
4.约束
含义:一种限制,用来限制表中的数据,为了保证数据的可靠性和准确性
CREATE TABLE 表名(
字段名 字段类型 列级约束
表级约束
)
添加约束的时机:
1.创建表时
2.修改表时
约束的分类:
列级约束:支持六大约束,外键约束没有效果
表级约束:除了非空,默认约束其他都支持
常见约束:
难点: 六大约束:
not null:非空约束,用来保证该字段不能为空(姓名,学号) default:默认约束,用来保证该字段有默认值(性别)
primary key:主键约束,用来保证该字段的值具有唯一性,并且非空(员工编号)
unique:唯一约束,用来保证该字段的值具有唯一性,对应的值可以为空(座位)
check:检查约束【mysql不支持check约束】(性别)
foreing key:外键约束,用来限制两个表的关系(reference连接的关键字)
要有保证连接两表的字段
用来保证该字段的值必须来自主表的关联列
4.1创建表时添加约束
列级约束:直接在字段名和类型后面追加约束类型,支持默认,非空,唯一,主键
表级约束:在所有字段的最后面
CONSTRAINT 约束名 约束类型(字段名)【reference 表名(字段名)】
#通用写法,创建表的时候列级约束以及表级约束都有添加
CREATE TABLE if not EXISTS stuifo(
id INT PRIMARY KEY, #主键
stuName VARCHAR(20) PRIMARY KEY,#非空
gender CHAR(1) CHECK(gender='男' OR gender='女'), #检查
seat INT UNIQUE,#唯一
age INT,
majorId INT,#外键
CONSTRAINT fk_stuifo_major FOREIGN KEY(majorId) REFERENCES major(id)
);
#查询某表中的索引,包括主键,外键,唯一键
SHOW INDEX FROM stuifo;
4.2修改表时添加约束:
列级约束:ALTER TABLE 表名 MODIFY COLUMN 字段 字段类型 新约束;
表级约束:ALTER TABLE 表名 MODIFY add 新约束(字段);
#在修改表时添加非空,默认,主键,外键约束
ALTER TABLE stuifo MODIFY COLUMN stuName VARCHAR(20) NOT NULL;
ALTER TABLE stuifo MODIFY COLUMN age INT DEFAULT 18;
ALTER TABLE stuifo MODIFY COLUMN id INT PRIMARY KEY;#列级
ALTER TABLE stuifo ADD PRIMARY KEY(id);#表级
ALTER TABLE stuifo ADD CONSTRAINT fk_syuifo_major
FOREIGN KEY(majorId) REFERENCES major(id);#外键
4.3修改表时删除约束
#修改表时删除约束
#1.删除非空约束
ALTER TABLE stuifo MODIFY COLUMN stuName VARCHAR(20);
#2.删除主键约束
ALTER TABLE stuifo DROP PRIMARY KEY;
#3.删除外键约束???
ALTER TABLE stuifo DROP FOREIGN KEY fk_syuifo_major;
5.标识列
含义:类似于约束得自增长列
可以不用手动插入值,系统提供默认的序列值
auto_increment_increment每次增长的步长值
auto_increment_offset偏移量(起始值)
特点:1.一个表里的标识列至多只能有一个
2.标识列不一定和主键约束一起使用
标识列必须和约束一起使用
3.标识列可以进行数据设置 set auto_increment_increment=值(步长)
添加标识列的时机:
1.创建表时
2.修改表时添加
alter table 表 modify column 字段 约束 auto_increment;
3.修改表时删除
alter table 表 modify column 字段;
#标识列
#创建时设置标识列
CREATE TABLE tab_inndentity(
id INT PRIMARY KEY auto_increment,
NAME VARCHAR(20)
);
INSERT INTO tab_inndentity VALUES(
1,'Ellen'
);
INSERT INTO tab_inndentity VALUES(
NULL,'Ivy'
);
#查看步长,起始值
SHOW VARIABLES LIKE '%auto_increment%';
#设置自增步长
SET auto_increment_increment=3;
八:DCL语言的学习:事务控制语句
1. 事务:一个或一组sql语句组成一个执行单元,这个执行单元要么全部执行,要么全部不执 行,相互依赖
2. 事务处理:
回滚:事务执行失败,所有受到影响的数据将回到事物开始之前的状态
反之如果单元中的所有sql语句都执行成功,则事务被顺利执行
3.事务的特性ACID:
3.1原子性(Atomicity)
一个事物不可分割,执行单元要么全部执行,要么全部不执行
3.2一致性(Consistency)
一个事物会使数据从一个统一状态切换到另一个统一状态
3.3隔离性(Isolation)
事物之间的各自sql语句执行过程不受其他事物打扰
3.4持久性(Durability)
一个事物一旦提交,则会永久的改变数据库的数据
4.事物创建
检查事务提交的状态
4.1隐式事务的创建:事务没有明显的开启和结束的标记
insert update delete
4.2显式事务的创建:事务有明显的开启和结束的标记
1.注意,显示事务的创建之前必须禁用自动提交功能
SET autocommit=0;
2.开启事务
SET autocommit=1;
START TRANSACTION;(可选)
3.编写事务中sql语句(select insert update delete)
语句一;
语句二;
......
4.结束事务
Rollback;回滚
Commit;提交
Savepoint;设置节点保存
##显示自动提交功能
SHOW ENGINES;
SHOW VARIABLES LIKE 'autocommit';
##关闭事务
SET autocommit=0;
##开启事务
SET autocommit=1;
START TRANSACTION;
(1)CREATE TABLE account(
id INT PRIMARY KEY auto_increment,
username VARCHAR(20),
balance DOUBLE
);
INSERT INTO account(username,balance)
VALUES('玄彬',1000),('元彬',1000);
SELECT * FROM account;
SET autocommit=0;
#创建事务sql语句
#成功
UPDATE account SET balance=500 WHERE username='玄彬';
UPDATE account SET balance=1500 WHERE username='元彬';
#结束事务
COMMIT;
SELECT * FROM account;
#失败
UPDATE account SET balance=1000 WHERE username='玄彬';
UPDATE account SET balance=1000 WHERE username='元彬';
#回滚事务
ROLLBACK;
SELECT * FROM account;
九:视图的讲解
含义:虚拟的表,和数据库中的普通表一样使用
创建:create view 视图名
as 查询语句
删除:drop view 视图名
来源:oschina
链接:https://my.oschina.net/u/4394252/blog/4360156