目录
一.数据库
1.概念
2.数据库的分类
二.数据库管理系统
1.概念
2.常见数据库管理系统
三.Mysql
1.简介
2.MYSQL目录结构
3.MySQL配置文件
四.SQL语言
1.概念
2.基本命令
查看MySQL中所有数据库
创建自定义数据库
查看数据库创建信息
修改数据库
删除数据库
查看当前所使用的数据库
使用数据库
五.数据查询
1 数据库表的基本结构
2 基本查询
2.1查询所有列
2.2查询部分列
2.3对列中的数据进行运算 (注意:%是占位符,而非模运算符)
2.4列的别名
2.5查询结果去重
3排序查询
3.1依据单列排序
3.2依据多列排序
4条件查询
4.1等值判断
4.2逻辑判断(and、or、not)
4.3 不等值判断(> 、< 、>= 、<= 、!= 、<>)
4.4 区间判断(between and)
4.5NULL值判断(IS NULL,IS NOT NULL)
4.6 枚举查询( IN (值 1,值 2,值 3 ) )
4.7模糊查询
4.8 分支结构查询
5时间查询
5.1获得当前系统时间
6 字符串查询
6.1字符串应用
7聚合函数
8分组查询
9 分组过滤查询
10限定查询
11查询总结
11.1SQL 语句编写顺序
11.2SQL 语句执行顺序
12子查询(作为条件判断)
13子查询(作为枚举查询条件)
14子查询(作为一张表)
15 合并查询
16表连接查询
16.1内连接查询(INNER JOIN ON)
16.2表连接查询
16.3左外连接(LEFT JOIN ON)
16.4右外连接(RIGHT JOIN ON)从上
数据库是按照数据结构来组织,存储和管理数据的仓库。
网状结构数据库:美国通用电气公司IDS,以节点形式存储和访问。
层次结构数据库:IBM公司IMS定向有序的树状结构实现存储和访问。
关系结构数据库:Oracle、DB2、MySQL、SQL Server,以表格(Table)存储,多表间建立关联关系,通过分类、合并、连接、选取等运算实现访问。
非关系型数据库:ElastecSearch、MongoDB、Redis,多数使用哈希表,表中以键值(key-value)的方式实现特定的键和一个指针指向的特定数据。
数据库管理系统(DataBase Management System,DBMS):指一种操作和管理数据库的大型软件,用于建立、使用和维护数据库,对数据库进行统一管理和控制,以保证数据库的安全性和完整性。用户通过数据库管理系统访问数据库中的数据。
Oracle:被认为是业界目前比较成功的关系型数据库管理系统。Oracle数据库可以运行在UNIX、Windows等主流操作系统平台,完全支持所有的工业标准,并获得最高级别的ISO标准安全性认证。
DB2:IBM公司的产品,DB2数据库系统采用多进程多线索体系结构,其功能足以满足大中公司的需要,并可灵活地服务于中小型电子商务解决方案。
SQL Server:Microsoft 公司推出的关系型数据库管理系统。具有使用方便可伸缩性好与相关软件集成程度高等优点。
MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS(Relational Database Management System,关系数据库管理系统) 应用软件之一。
核心文件介绍
文件夹名称 | 内容 |
---|---|
bin | 命令文件 |
lib | 库文件 |
include | 头文件 |
Share | 字符集、语言等信息 |
在MySQL安装目录中找到my.ini文件,并打开my.ini文件查看几个常用配置参数(不用去修改)
SQL(Structured Query Language)结构化查询语言,用于存取数据、更新、查询和管理关系数据库系统的程序设计语言。
对于数据库的操作,需要在进入MySQL环境下进行指令输入,并在一句指令的末尾使用 ; 结束。
- mysql> SHOW DATABASES;
数据库名称 | 描述 |
---|---|
information_schema | 信息数据库,其中保存着关于所有数据库的信息(元数据)。 元数据是关于数据的数据,如数据库名或表名,列的数据类型,或访问权限等。 |
mysql | 核心数据库,主要负责存储数据库的用户、权限设置、关键字等, 以及需要使用的控制和管理信息,不可以删除。 |
performance_schema | 性能优化的数据库,MySQL 5.5版本中新增的一个性能优化的引擎。 |
sys | 系统数据库,MySQL5.7版本中新增的可以快速的了解元数据信息的系统库 便于发现数据库的多样信息,解决性能瓶颈问题。 |
- mysql> CREATE DATABASE mydb1; #创建mydb数据库
- mysql> CREATE DATABASE mydb2 CHARACTER SET gbk; #创建数据库并设置编码格式为gbk
- mysql> CREATE DATABASE IF NOT EXISTS mydb4; #如果mydb4数据库不存在,则创建;如果存在,则不创建。
- mysql> SHOW CREATE DATABASE mydb2; #查看创建数据库时的基本信息
- mysql> ALTER DATABASE mydb2 CHARACTER SET gbk; #查看创建数据库时的基本信息
- mysql> DROP DATABASE mydb1; #删除数据库mydb1
- mysql> select database(); #查看当前使用的数据库
- mysql> USE mydb1; #使用mydb1数据库
关系结构数据库是以表格(Table)进行数据存储,表格由“行”和“列”组成
注意:执行查询语句返回的结果集是一张虚拟表!
语法:SELECT 列名 FROM 表名 ;
关键字 | 描述 |
---|---|
SELECT | 指定要查询的列 |
FROM | 指定要查询的表 |
- #查询员工表中所有员工的所有信息(所有列)
- SELECT 所有列的列名 FROM t_employees;
- SELECT * FROM t_employees;
注意:*的方式需转换成全列名,效率低,可读性差。
#查询员工表中所有员工的编号、名字、邮箱
- SELECT employee_id,first_name,email FROM t_employees;
#查询员工表中所有员工的编号、名字、年薪
- SELECT employee_id , first_name , salary*12 FROM t_employees;
算数运算符 | 描述 |
---|---|
+ | 两列做加法运算 |
- | 两列做减法运算 |
* | 两列做乘法运算 |
/ | 两列做除法运算 |
#查询员工表中所有员工的编号、名字、年薪(列名均为中文)
- SELECT employee_id as "编号" , first_name as "名字" , salary*12 as "年薪" FROM t_employees;
DISTINCT 列名
#查询员工表中所有经理的ID。
- SELECT DISTINCT manager_id FROM t_employees;
语法:SELECT 列名 FROM 表名 ORDER BY 排序列 [排序规则]
排序规则 | 描述 |
---|---|
ASC | 对前面排序列做升序排序 |
DESC | 对前面排序列做降序排序 |
#查询员工的编号,名字,薪资。按照工资高低进行降序排序。
- SELECT employee_id , first_name , salary
- FROM t_employees
- ORDER BY salary DESC;
#查询员工的编号,名字,薪资。按照工资高低进行升序排序(薪资相同时,按照编号进行升序排序)。
- SELECT employee_id , first_name , salary
- FROM t_employees
- ORDER BY salary DESC , employee_id ASC;
语法:SELECT 列名 FROM 表名 WHERE 条件
关键字 | 描述 |
---|---|
WHERE 条件 | 在查询结果中,筛选符合条件的查询结果,条件为布尔表达式 |
#查询薪资是11000的员工信息(编号、名字、薪资)
- SELECT employee_id , first_name , salary
- FROM t_employees
- WHERE salary = 11000;
注意:与java不同(==),mysql中等值判断使用(=)
#查询薪资是11000并且提成是0.30的员工信息(编号、名字、薪资)
SELECT employee_id , first_name , salary
FROM t_employees
WHERE salary = 11000 AND commission_pct = 0.30;
#查询员工的薪资在6000~10000之间的员工信息(编号,名字,薪资)
SELECT employee_id , first_name , salary
FROM t_employees
WHERE salary >= 6000 AND salary <= 10000;
#查询员工的薪资在6000~10000之间的员工信息(编号,名字,薪资)
SELECT employee_id , first_name , salary
FROM t_employees
WHERE salary BETWEEN 6000 AND 10000; #闭区间,包含区间边界的两个值
注:在区间判断语法中,小值在前,大值在后,反之,得不到正确结果
IS NULL
列名 IS NULL
IS NOT NULL
列名 IS NOT NULL
#查询部门编号为70、80、90的员工信息(编号,名字,薪资 , 部门编号
SELECT employee_id , first_name , salary , department_id
FROM t_employees
WHERE department_id IN(70,80,90);
注:in的查询效率较低,可通过多条件拼接。
LIKE _ (单个任意字符) 列名 LIKE '张_'
LIKE %(任意长度的任意字符) 列名 LIKE '张%'
CASE
WHEN 条件1 THEN 结果1
WHEN 条件2 THEN 结果2
WHEN 条件3 THEN 结果3
ELSE 结果
END
语法:SELECT 时间函数([参数列表])
经验:执行时间函数查询,会自动生成一张虚表(一行一列)
时间函数 | 描述 |
---|---|
SYSDATE() | 当前系统时间(日、月、年、时、分、秒) |
CURDATE() | 获取当前日期 |
CURTIME() | 获取当前时间 |
WEEK(DATE) | 获取指定日期为一年中的第几周 |
YEAR(DATE) | 获取指定日期的年份 |
HOUR(TIME) | 获取指定时间的小时值 |
MINUTE(TIME) | 获取时间的分钟值 |
DATEDIFF(DATE1,DATE2) | 获取DATE1 和 DATE2 之间相隔的天数 |
ADDDATE(DATE,N) | 计算DATE 加上 N 天后的日期 |
#时间
#当前日期
SELECT SYSDATE();
SELECT NOW();
SELECT SYSDATE(),FIRST_NAME FROM t_employees ;
#当前日期
SELECT CURDATE();
#当前时间
SELECT CURTIME();
#一年的第几周
SELECT WEEK(NOW());
SELECT YEAR(t.`HIRE_DATE`) FROM t_employees t;
#yyyy-MM-dd %y%m%d 获取日期
SELECT DATE_FORMAT(NOW(),'%y年%m月%d日');
#小时和分钟
SELECT HOUR(NOW()),MINUTE(NOW());
# 判断2个日期之间相差
SELECT DATEDIFF(NOW(),'2021-4-1');
#把日期添加 整数加,负数减
SELECT ADDDATE(NOW(),-2);
#补充日期查询 mysql 里面日期的字符串可以直接和日期类型的值直接进行对比判断
#查询日职日期在1987-1-1 到1997-1-1之间的所有员工
SELECT * FROM t_employees WHERE HIRE_DATE >= '1987-1-1' AND HIRE_DATE <= '1989-9-20';
语法: SELECT [字符串函数 ([参数列表])]()
字符串函数 | 说明 |
---|---|
CONCAT(str1,str2,str....) | 将 多个字符串连接 |
INSERT(str,pos,len,newStr) | 将str 中指定 pos 位置开始 len 长度的内容替换为 newStr |
LOWER(str) | 将指定字符串转换为小写 |
UPPER(str) | 将指定字符串转换为大写 |
SUBSTRING(str,num,len) | 将str 字符串指定num位置开始截取 len 个内容 |
#字符串函数
#字符串拼接
SELECT CONCAT('我','爱','java');
SELECT CONCAT('1','+','1','=','2','?');
SELECT CONCAT(e.`FIRST_NAME`,'-',e.`LAST_NAME`) FROM t_employees e;
SELECT CONCAT(e.`FIRST_NAME`,e.`LAST_NAME`) FROM t_employees e;
#字符串替换 insert ==>replace 下标1开始
SELECT INSERT('我爱java',2,1,'最爱');
SELECT INSERT('我爱芹芹啊',2,1,'最爱');
# 大写 小写
SELECT UPPER(e.`FIRST_NAME`),LOWER(e.`FIRST_NAME`) FROM t_employees e;
# substring 下标,长度
SELECT SUBSTRING('我爱java',3);
SELECT SUBSTRING('我爱java',3,2);
聚合函数 | 说明 |
---|---|
SUM() | 求所有行中单列结果的总和 |
AVG() | 平均值 |
MAX() | 最大值 |
MIN() | 最小值 |
COUNT() | 求总行数 |
#聚合函数 1行1列
#查询工资最高的
SELECT MAX(SALARY) FROM t_employees;
#不能直接这么做,分组中可以使用聚合函数作为条件
#SELECT * FROM t_employees where SALARY = max(SALARY);
#查询工资最低的
SELECT MIN(SALARY) FROM t_employees;
#查询所有工资和
SELECT SUM(SALARY) FROM t_employees;
#查询工资平均值
SELECT AVG(SALARY) FROM t_employees;
注意:聚合函数自动忽略null值,不进行统计。
语法:SELECT 列名 FROM 表名 WHERE 条件 GROUP BY 分组依据(列);
关键字 | 说明 |
---|---|
GROUP BY | 分组依据,必须在 WHERE 之后生效 |
#分组
#查询个部门的人数
SELECT DISTINCT DEPARTMENT_ID FROM t_employees;
SELECT COUNT(1) FROM t_employees WHERE DEPARTMENT_ID = 90;
#使用分组查询字段,只能是聚合函数或者是分组的字段,如果加入其它字段会出现数据错误问题
SELECT COUNT(1),DEPARTMENT_ID,FIRST_NAME
FROM t_employees GROUP BY DEPARTMENT_ID ;
#查询个部门,最高工资,最低工资,工资和,平均工资
SELECT DEPARTMENT_ID,COUNT(EMPLOYEE_ID),SUM(SALARY),MAX(SALARY),MIN(SALARY),AVG(SALARY)
FROM t_employees GROUP BY DEPARTMENT_ID;
语法:SELECT 列名 FROM 表名 WHERE 条件 GROUP BY 分组列 HAVING 过滤规则
关键字 | 说明 |
---|---|
HAVING 过滤规则 | 过滤规则定义对分组后的数据进行过滤 |
#统计60、70、90号部门的最高工资
#思路:
#1). 确定分组依据(department_id)
#2). 对分组后的数据,过滤出部门编号是60、70、90信息
#3). max()函数处理
SELECT department_id , MAX(salary)
FROM t_employees
GROUP BY department_id
HAVING department_id in (60,70,90)
# group确定分组依据department_id
#having过滤出60 70 90部门
#select查看部门编号和max函数。
SELECT 列名 FROM 表名 LIMIT 起始行,查询行数
关键字 | 说明 |
---|---|
LIMIT offset_start,row_count | 限定查询结果的起始行和总行数 |
- #查询表中前五名员工的所有信息
- SELECT * FROM t_employees LIMIT 0,5;
注意:起始行是从 0 开始,代表了第一行。第二个参数代表的是从指定行开始查询几行
分页查询:一页显示 10 条,一共查询三页
#思路:第一页是从 0开始,显示 10 条
- SELECT * FROM LIMIT 0,10;
#第二页是从第 10 条开始,显示 10 条
- SELECT * FROM LIMIT 10,10;
#第三页是从 20 条开始,显示 10 条
- SELECT * FROM LIMIT 20,10;
在分页应用场景中,起始行是变化的,但是一页显示的条数是不变的
SELECT 列名 FROM 表名 WHERE 条件 GROUP BY 分组 HAVING 过滤条件 ORDER BY 排序列(asc|desc)LIMIT 起始行,总条数
1.FROM :指定数据来源表
2.WHERE : 对查询数据做第一次过滤
3.GROUP BY : 分组
4.HAVING : 对分组后的数据第二次过滤
5.SELECT : 查询各字段的值
6.ORDER BY : 排序
7.LIMIT : 限定查询结果
SELECT 列名 FROM 表名 Where 条件 (子查询结果)
查询工资大于Bruce 的员工信息
#1.先查询到 Bruce 的工资(一行一列)
- SELECT SALARY FROM t_employees WHERE FIRST_NAME = 'Bruce';#工资是 6000
#2.查询工资大于 Bruce 的员工信息
- SELECT * FROM t_employees WHERE SALARY > 6000;
#3.将 1、2 两条语句整合
- SELECT * FROM t_employees WHERE SALARY > (SELECT SALARY FROM t_employees WHERE FIRST_NAME = 'Bruce' );
SELECT 列名 FROM 表名 Where 列名 in(子查询结果);
工资高于60部门所有人的信息
#1.查询 60 部门所有人的工资(多行单列)
SELECT SALARY from t_employees WHERE DEPARTMENT_ID=60;
#2.查询高于 60 部门所有人的工资的员工信息(高于所有)
select * from t_employees where SALARY > ALL(select SALARY from t_employees WHERE DEPARTMENT_ID=60);
#。查询高于 60 部门的工资的员工信息(高于部分)
select * from t_employees where SALARY > ANY(select SALARY from t_employees WHERE DEPARTMENT_ID=60);
注意:当子查询结果集形式为多行单列时可以使用 ANY 或 ALL 关键字
SELECT 列名 FROM(子查询的结果集)WHERE 条件;
查询员工表中工资排名前 5 名的员工信息
#思路:
#1. 先对所有员工的薪资进行排序(排序后的临时表)
select employee_id , first_name , salary
from t_employees
order by salary desc
#2. 再查询临时表中前5行员工信息
select employee_id , first_name , salary
from (临时表)
limit 0,5;
#SQL:合并
select employee_id , first_name , salary
from (select employee_id , first_name , salary from t_employees order by salary desc) as temp
limit 0,5;
将子查询 ”多行多列“的结果作为外部查询的一张表,做第二次查询。
注意:子查询作为临时表,为其赋予一个临时表名。
SELECT * FROM 表名 1 UNION SELECT * FROM 表名 2
SELECT * FROM 表名 1 UNION ALL SELECT * FROM 表名 2
注意:合并结果的两张表,列数必须相同,列的数据类型可以不同
经验:使用 UNION 合并结果集,会去除掉两张表中重复的数据
SELECT 列名 FROM 表1 连接方式 表2 ON 连接条件 (连接条件是表一与表二共有的字段)
#1.查询所有有部门的员工信息(不包括没有部门的员工) SQL 标准
SELECT * from t_employees e INNER JOIN
t_departments d ON e.DEPARTMENT_ID=d.DEPARTMENT_ID;
#2.查询所有有部门的员工信息(不包括没有部门的员工) MYSQL
SELECT * from t_employees e,t_departments d
where e.DEPARTMENT_ID=d.DEPARTMENT_ID;
#查询所有员工工号、名字、部门名称、部门所在国家ID
SELECT * FROM t_employees e
INNER JOIN t_departments d
on e.department_id = d.department_id
INNER JOIN t_locations l
ON d.location_id = l.location_id
在 MySql 中,第二种方式也可以作为内连接查询,但是不符合 SQL 标准
而第一种属于 SQL 标准,与其他关系型数据库通用
#查询所有员工信息,以及所对应的部门名称(没有部门的员工,也在查询结果中,部门名称以NULL 填充)
SELECT e.employee_id , e.first_name , e.salary , d.department_name
FROM t_employees e
LEFT JOIN t_departments d
ON e.department_id = d.department_id;
注意:左外连接,是以左表为主表,依次向右匹配,匹配到,返回结果
匹配不到,则返回 NULL 值填充