数据库 (基础数据库知识 )

目录:

  • 一. 数据库基础知识
    • 1. 数据库介绍
      • 1.1 什么是数据库
      • 1.2 数据库的分类
      • 1.3 使用数据库的原因
      • 1.4 Sql的优点
      • 1.5 数据库的特点
      • 1.6 数据库服务的操作
    • 2.Mysql的常见命令
    • 3. Sql 的语句规范
    • 4.DQL语言(数据查询语言)
      • 4.1 基础查询
      • 4.2 条件查询
      • 4.3 排序查询
      • 4.4 常见函数---单行函数
        • 4.4.1字符函数
        • 4.4.2 数字函数
        • 4.4.3 日期函数
        • 4.4.4 其他函数
        • 4.4.5 流程控制函数
      • 4.5 常见函数---分组函数
      • 4.6 分组查询
      • 4.7 连接查询
        • 4.7.1 等值连接:
        • 4.7.2 非等值连接
        • 4.7.3 自连接
      • 4.8 连接查询(99标准)
        • 4.8.1 等值连接
        • 4.8.2 非等值连接
        • 4.8.3 自连接
        • 4.8.4 外连接
      • 4.9 子查询
      • 4.10 分页查询
      • 4.11联合查询
    • 5.DML语言 (数据操作语言)
      • 5.1 插入语句
      • 5.2 修改语句
      • 5.3 删除语句
    • 6. DDL语言 (数据定义语言)
      • 6.1 库的管理
      • 6.2 表的操作
      • 6.3 数据类型
      • 6.4 时间类型
      • 6.5 常见约束
      • 6.6 标识列

一. 数据库基础知识

1. 数据库介绍

1.1 什么是数据库

数据库,保存数据的仓库,体现我们电脑中,就是一个文件系统,然后把数据都保存在这些特殊的文件中,并且需要使用固定的语言(SQL语言)去操作文件中的数据
数据库(Database)是按照数据结构来组织、存储和管理数据的建立在计算机存储设备上的苍仓库
将程序中的数据保存到专业的软件中,这些软件称之为数据库

1.2 数据库的分类

分为关系型数据库和非关系型数据库

关系数据库: 数据库中的数据有关系 oracle Mysql SqiSever DB2
非关系数据库: 数据库中的数据没人有关系 NoSql Cloudant

关系型数据库:
关系型数据设置数据库的时候,需要使用E-R图来描述实体关系

DB 数据库(database)存储数据的仓库,他保存了一系列有组织的数据
DBMS 数据库管理系统,数据库是通过DBMS创建和操作的容器
SQL 结构化查询语言:专门用来与数据库通信的语言

1.3 使用数据库的原因

  1. 实现数据持久化
  2. 使用完整的管理系统统一管理,易于查询

1.4 Sql的优点

  1. 不是某个特定数据库供应商专有的语言,几乎所有DBMS都支持SQL
  2. 简单易学
  3. 一种强有力的语言,灵活使用其语言元素,可以进行非常复杂和高级的数据库操作

1.5 数据库的特点

  1. 将数据放到表中,表再放入库中.
  2. 一个数据库中可以有多个表,每个表都有一个名字,用来标识自己,表名具有唯一性
  3. 表具有一些特性,这些特性定 义了数据在表中如何存储,
  4. 表由列组成,我们也称为字段,所有表都是由一个或多个列组成的,每一列相当于属性
    DBMS分为:
    • 基于共享文件系统的DBMS(Access)
    • 基于客户机—服务器的DBMS(MySql Oracle SqlSever)

1.6 数据库服务的操作

  • 启动(启动的名字需要查看服务里面mysql的具体name)
    net stop mysql
  • 关闭
    net start mysql
    数据库 (基础数据库知识 )_第1张图片
  • 登录
    mysql -h localhost -u root -p
    root是名字 p是密码 h是host 表示本地
    数据库 (基础数据库知识 )_第2张图片
    如果进入失败 mysqll不是内部命令 需要配置环境变量 只需将mysql的bin目录路径加入到系统的path中即可
  • 退出
    exit
    数据库 (基础数据库知识 )_第3张图片

2.Mysql的常见命令

  • 查看数据库中有多少仓库 也就是多少个数据库
    show databases;
    结尾必须用分号 要不不执行
    数据库 (基础数据库知识 )_第4张图片
  • 进入数据库
    use 数据库名
    在这里插入图片描述
  • 进入数据库的表中
    show tables;(注意 分号)
    数据库 (基础数据库知识 )_第5张图片
  • 直接查看某个数据库中的表(仅仅只是展示)
    show tables from ssm_crud;
    数据库 (基础数据库知识 )_第6张图片
  • 查看当前定位于哪个数据库
    select database();
    数据库 (基础数据库知识 )_第7张图片
  • 创建表
    create table 表名(列名 类型,列名 类型);
    数据库 (基础数据库知识 )_第8张图片
  • 展示表的详细内容
    desc stuinfo;
    数据库 (基础数据库知识 )_第9张图片
  • 查看Mysql的版本
  1. select version();
    数据库 (基础数据库知识 )_第10张图片
  2. C:\Users\tjk>mysql --version 这条命令必须是在mysql退出情况下使用
    在这里插入图片描述

3. Sql 的语句规范

  • 不区分大小写 但是建议关键字大写 表名和列名小写
  • 每条命令用分号结尾
  • 每条命令根据需要可以进行换行
  • 注释:
    单行注释 #注释文字
    – 注释文字
    多行注释 / *注释文字 */

4.DQL语言(数据查询语言)

4.1 基础查询

  • 语法:
    select 查询列表
    from 表名;
  • 特点:
  1. 查询列表可以是:表中的字段 常量值 表达式 函数
  2. 查询结果是一个虚拟的表格

查询表中的单个字段

SELECT last_name from employees;

查询表中多个字段

SELECT last_name,first_name from employees;

查询表中的所有字段

SELECT *from employees;

选中哪个库去执行sql
在sql查询的最前端写

use 库名

着重号 ‘ ’
区分是否为关键字 为`不是引号

select `first_name` from `employees`;

查询常量值

select 100

查询字符串

select 'join';

查询表达式

select 100%2;

查询函数值

SELECT VERSION();

起别名(如果别名里面有特殊字段或者空格 建议用单引号或者双引号)
好处:

  1. 便于理解
  2. 如果要查询的字段有重名的情况,使用别名可以区分开来
select name as name1 from emp;
#或者
select name name1 from emp;

去重— distinct
查询员工表中的涉及到的所有部门编号

select DISTINCT  department_id from employees;

"+"的作用
查询员工的名和姓连接在一起并显示为姓名

#+ 号的作用   将字符型转换为数值型  如果转换成功就为数值型
#                   转换失败则字符型相当于0  再做加法运算
# 只要一方为null则 结果为null  
SELECT '123'+123;
SELECT 'tjk'+123;

连接字符串 concat(str, str,str)

#concat(str, str,str)
select CONCAT(last_name,first_name) as 姓名  from employees;

ifnull 判断是否为空

#IFNULL(判断是否空的字段,如果是的返回结果)
select IFNULL(commission_pct,0) AS 奖金率 from employees;

4.2 条件查询

  • 语法
    SELECT 查询列表
    from 表名
    where 筛选条件
  • 分类
    1. 按条件表达式筛选
      条件运算符 > < = != <> >= <=
    2. 按逻辑表达式筛选
      逻辑运算符
      && || !
      and or not
    3. 模糊查询
      like
      between and
      in
      is null
      like
#查询 员工姓名中包含字符a 的员工信息‘
select
   *
FROM employees
WHERE first_name LIKE '%a%';

通配符:
% 任意多个字符 包含0个字符
_ 任意单个字符

#查询员工名中第三个字符为a 第五个字符为a的员工信息
SELECT last_name ,salary FROM employees WHERE last_name like
 '__a_a%';
 
 #查询员工名中第二个字符为_的员工
 SELECT last_name from  employees WHERE last_name LIKE '_\_%'; 

声明某个字符是转义的标志

 SELECT last_name from  employees WHERE last_name LIKE '_a_%' ESCAPE 'a';

between… and…
注意:
包含两个端点的值
且端点不能颠倒 必须是从小到大

 #查询员工编号在100-----120之间
 SELECT *FROM employees where employee_id BETWEEN 100 and 120;

in()

 #查询员工的工种编号AD_PRES    AD_VP    IT_PROG
 select last_name, job_id FROM employees where  job_id IN('AD_PRES','AD_VP','IT_PROG');

is null

 #查询没有奖金的员工和奖金率
 SELECT last_name ,commission_pct from employees where commission_pct is NULL;

is not null

 #查询有奖金的员工和奖金率
 SELECT last_name ,commission_pct from employees where commission_pct is NOT NULL;

安全等于<=>
既可以判断null值,又可以判断普通的数值

#查询没有奖金的员工和奖金率
 SELECT last_name ,commission_pct from employees where commission_pct <=> NULL;

ifnull( , )

 # 查询员工号为176的员工的姓名和部门号和年薪
select employee_id,last_name,salary*12*(1+IFNULL(commission_pct,0)) as 年薪 
from employees where employee_id=176;

4.3 排序查询

语法:

 SELECT 查询列表
  FROMwhere 筛选条件
	ORDER BY 排序列表  asc| DESC

注意:

  1. asc 是升序
    desc是 降序
    如果不写会默认为升序
  2. ORDER BY 字句中可以支持单个字段 多个字段 表达式 函数 别名
  3. ORDER BY 字句一般是当字句查询语句的最后面,LIMIT 子句除外
  • 案例:查询员工信息 要求工资由高到低
SELECT last_name,salary from employees ORDER BY salary DESC;
  • 案例:查询部门编号>=90的员工信息,按入职时间先后进行排序
SELECT * FROM employees where department_id>=90 ORDER BY hiredate ;
  • 查询员工的姓名 部门号和年薪 按年薪降序 按姓名升序
SELECT last_name,department_id,salary*12*(1+IFNULL(commission_pct,0)) 
年薪 from employees ORDER BY 年薪 DESC,last_name ASC;
  • 选择工资不在8000到17000的员工的姓名和工资 按工资降序
SELECT last_name,salary FROM employees where salary NOT BETWEEN 8000 and 17000
ORDER BY salary DESC;
  • 查询邮箱中包含e的员工信息,并按照邮箱的字节数降序 再按照部门号升序
SELECT *from employees WHERE email LIKE '%e%' ORDER BY LENGTH(email) DESC,department_id ASC;

4.4 常见函数—单行函数

  • 概念:类似于java的方法,将一组逻辑语句封装到方法体,对外暴露方法名
  • 好处
  1. 隐藏了实现细节
  2. 提高代码的复用性
  • 调用
select 函数名(实参列表)from
  • 特点
  1. 叫什么函数名
  2. 干什么(函数功能)
  • 分类
    1. 单行函数
      concat length ifnull
    2. 分组函数
      功能:做统计使用,又称为统计函数 聚合函数 组函数

4.4.1字符函数

  • length(长度)
select LENGTH("tjk");
  • concat(连接)
SELECT CONCAT(last_name,"-",first_name) from employees;
  • upper(变大写) lower(变小写)
SELECT UPPER("tjk");	


示例  将姓名变大写  名变小写 然后拼接
select CONCAT(UPPER(first_name),"--",LOWER(last_name)) from employees;
  • SUBSTR(str FROM pos FOR len) (截取从标记字符开始后面的所有字符)
SELECT SUBSTR("tjk xixixi",5);# 所有的标记都是从1开始算的   在sql中
  • SUBSTR(str,pos,len)//从标记的位置算起 截取len长度
  • INSERT(str,strsub)//在str中strsub存在的位置从第一个字符开始算起 如果找不到返回0
  • TRIM([remstr FROM] str) 去掉str中的规定字符 如下 如果不规定 则默认空格
SELECT TRIM("                tjk");
SELECT TRIM('-'FROM"------------tjk");
  • SELECT LPAD(str,len,padstr) 规定在str左边填充padstr len个字符
  • RPAD(str,len,padstr) 规定在str右边填充padstr len个字符
  • REPLACE 替换指定字符串中的字符串为另一字符串 更换的是全部
SELECT REPLACE("tjkdiditjktjktdiditjk",'didi','-');

4.4.2 数字函数

  • roubnd(num)—>四舍五入
SELECT ROUND(3.11);
SELECT ROUND(3.11,1);#默认保留几位小数
  • CEIL(NUM) 向上取整
SELECT CEIL(5.1);
  • FLOOR(num);向下取整
SELECT FLOOR(4.2);
  • TRUNCATE(X,D) 保留几位 但是不进行四舍五入 只进行截取
SELECT TRUNCATE(2.11,1);  
  • MOD(x,y) 取余
SELECT MOD(10,3);

4.4.3 日期函数

  • NOW() —返回当前日期+时间
    SELECT NOW();
  • CURRENT_DATE(); —返回当前系统的日期
  • SELECT CURRENT_DATE;
SELECT CURDATE();
  • CURRENT_TIME();----返回当前系统的时间
SELECT CURRENT_TIME();
SELECT CURTIME();
  • YEAR(DATA);—>找出当前日期的年
SELECT YEAR('1999-01-02');
  • MONTH()---->获取当前日期的月
SELECT MONTH('1999-01-01');
  • DAY()—>获取当前时间的 日
select DAY("1999-01-01");
  • STR_TO_DATE(‘1999-01-01’,’%Y-%m-%d’) —>按照特定格式将字符串转换为日期类型
SELECT STR_TO_DATE('1999-01-01','%Y-%m-%d') as 日期;
  • DATE_FORMAT(date,format) —>按照特定格式将日期转换为字符串
SELECT DATE_FORMAT(NOW(),'%Y年-%m月-%d日');

4.4.4 其他函数

SELECT VERSION();# 版本号
select DATABASE();#数据库
SELECT USER();#返回用户

4.4.5 流程控制函数

  • IF( , , )if函数类似于逻辑运算符
SELECT IF(5>2,1,0);
  • case的第一种情况(case后面跟内容了)

    /*
    CASE 要判断的字段或表达式
    WHEN 常量一 THEN 要显示的值1或语句1
    WHEN 常量二 THEN 要显示的值或语句2

    ELSE
    要显示的值n或语句n
    END CASE;
    */
SELECT salary 原始工资,department_id,CASE department_id
	WHEN 30 THEN  '一倍'
	WHEN  40 THEN '二倍'
	WHEN 50 THEN '三倍'
	ELSE salary 
	END AS 新工资
	FROM employees;
  • case语句的第二种情况(case 后面没有跟内容)
SELECT salary 原始工资,department_id,
CASE
    WHEN salary=30 then '是30啊'
		WHEN salary>30 THEN '比30大啊'
		WHEN salary<30 THEN '没有30大啊'
		ELSE '是其他啊'
END
FROM employees 

4.5 常见函数—分组函数

  • 分组函数
    /*
    功能:用作统计使用,又称为聚合函数或统计函数或组函数

分类:

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

*/

简单使用:

  • sum
SELECT SUM(salary) FROM employees;
  • avg
SELECT AVG(salary) FROM employees;
  • max
SELECT MAX(salary) FROM employees;
  • min
SELECT MIN(salary) FROM employees;
  • count—计数
SELECT COUNT(salary) FROM employees;

参数支持哪些类型
以上分组函数都会自动忽略null
可以和 DISTINCT 搭配

SELECT SUM(DISTINCT salary) from employees;
  • count 函数的详细介绍
  1. 普通用法
SELECT COUNT(salary) FROM employees;
  1. 计算总数据条数
select COUNT(*) FROM employees;
  1. 在查询表中加入一列为1 计算个数
SELECT count(1) FROM employees;

效率:
MYISAM存储引擎下 count()的效率高
INNODB存储引擎下 count(
)和count(1)效率差不多 比count (字段)要高一些
#和分组函数一同查询的字段有限制

SELECT avg(salary),employee_id FROM employees;-----无意义

4.6 分组查询

语法:

 SELECT  分组函数,列(要求出现在group by的后面)
FROMwhere 筛选条件 
GROUP BY 分组列表
ORDER BY 字句

注意:查询列表比较特殊 要求分组函数和group by后出现的
#引入 查询每个部门的平均工资

  • 添加分组前的筛选
SELECT department_id, AVG(salary) 
from employees 
GROUP BY department_id; 

案例 查询每个工种的最高工资

SELECT MAX(salary) ,job_id 
FROM employees 
GROUP BY job_id;

查询每个位置上部门的个数

SELECT COUNT(*),location_id 
FROM departments
 GROUP BY location_id;

#查询那个部门 员工个数大于2

  • 添加分组后的筛选
select COUNT(*) ,department_id
FROM employees 
GROUP BY department_id
HAVING COUNT(*)>2

查询每个工种有奖金的员工的最高工资》12000的公众编号和最高工资
#① 查询每个工种有奖金的员工的最高工资

SELECT MAX(salary), job_id
FROM employees
WHERE commission_pct IS NOT NULL
GROUP BY job_id
HAVING max(salary)>12000;

案例三 查询领导编号>102 的每个领导手下的最低工资

SELECT MIN(salary) 最低工资, manager_id
FROM employees
GROUP BY manager_id
HAVING manager_id>102;

特点:

  1. 分组查询中的筛选条件分为两类
- 数据源 位置 关键字
分组前筛选 原始表 GROUP BY 子句的前面 WHERE
分组后筛选 分组后的结果集 GROUP BY 子句的后面 HAVING

按员工姓名的长度分组 查询每一组的员工个数,筛选员工个数>5的数据

 SELECT count(*),LENGTH(last_name)
 FROM employees
 GROUP BY LENGTH(last_name);
 HAVING count(*)>5

按多个字段分组
案例 查询每个部门每个工种的员工的平均工资

SELECT avg(salary),department_id,job_id
FROM employees GROUP BY department_id,job_id

#添加排序
查询每个部门每个工种的员工的平均工资,并且按平均工资的高低显示

SELECT avg(salary),department_id,job_id
FROM employees GROUP BY department_id,job_id
ORDER BY avg(salary) DESC;

总结:
1. 分组函数做条件 一定放在having子句中
2. 能用分组前筛选的就用分组前的
3. GROUP BY 子句支持单个字段分组,多个字段分组(多个字段用逗号隔开 没有顺序要求) 也可以用表达式 但是用的较少
4. 后面也可以跟排序 ORDER BY

4.7 连接查询

含义: 又称多标查询,当查询的字段来自于多个表时,就会用到连接查询
笛卡尔乘积现象: 表有m行 表2有n行 结果为m*n行

发生原因: 没有有效的连接条件
如何避免: 添加有效的连接查询

分类:
按年代分类

sql92 仅支持内连接
sql99 (推荐) 支持内连接 外连接 交叉连接
按功能分类:
  • 内连接:
    -------------- 等值连接
    -------------- 非等值连接
    -------------- 自连接
  • 外连接:
    --------------左外链接
    -------------- 右外链接
    -------------- 全外连接
  • 交叉连接

4.7.1 等值连接:

注意:

  1. 多表等值连接的结果为多表的交集部分
  2. n表连接 至少需要n-1个连接条件
  3. 多表的顺序没有要求
  4. 一般需要为表起别名
  5. 可以搭配前面介绍的所有子句使用 比如分组 排序 筛选
SELECT boyName,beauty.`name` 
from boys,beauty 
where boyfriend_id=boys.id;

4.7.2 非等值连接

#非等值连接

SELECT salary,grade_level
FROM employees e,job_grades g
WHERE salary BETWEEN g.lowest_sal AND g.highest_sal;

4.7.3 自连接

实际上是等值连接 但是是一张表中的数据

SELECT e.employee_id,e.last_name,m.employee_id
FROM employees e,employees m
WHERE e.manager_id=m.manager_id; 

4.8 连接查询(99标准)

#sql99 语法
/*
语法:
   select 查询列表
	 from 表1 别名 连接类型  
	 join 表2 别名 
	 on 连接条件
	 where 筛选条件
	 GROUP BY 分组
	 HAVING 筛选条件
	 ORDER BY 排序列表
	 
 分类:
	 内连接:INNER
	 
	 外连接  
	     左外连接 LEFT
			 右外连接 RIGHT
			 全外  FULL
			 
	 交叉连接  CROSS

*/

4.8.1 等值连接

1.查询员工名 部门名

SELECT last_name,department_name
FROM departments d
INNER JOIN employees e
ON e.department_id=d.department_id

2.查询姓名中包含e的员工名和工种名(添加筛选)

SELECT last_name,job_title
FROM  employees e
INNER JOIN jobs j
ON e.job_id=j.job_id 
WHERE  e.last_name LIKE '%e%';

3.部门个数大于3 的城市名和部门个数 (添加分组和筛选)

select city,count(*) 部门个数
FROM departments d
INNER JOIN locations l
on d.location_id=l.location_id
GROUP BY city  #聚合以后才能进行条件审判
HAVING count(*)>3

ORDER BY 是进行排序筛选
4. 查询那个部门的员工个数>3 的部门名和员工个数 病案个数进行降序(添加排序)

select department_name, count(*) 员工个数
FROM employees e
INNER JOIN departments d
ON  e.department_id=d.department_id
GROUP BY e.department_id
HAVING count(*)>3
ORDER BY count(*) DESC
总结: 特点:
  1. 添加排序 分组 筛选
  2. inner 可以进行省略
  3. 筛选条件放在where后面 连接条件放在on后面 提高分离性 便于阅读
  4. inner join 连接和sql92 语法中的等值连接效果是一样的 都市查询多表的交集

4.8.2 非等值连接

查询员工的工资级别

	select salary,grade_level 
	FROM employees e
	INNER JOIN job_grades g
	ON e.salary BETWEEN g.lowest_sal AND g.highest_sal

4.8.3 自连接

查询员工的名字 上级的名字

	SELECT e.last_name,m.last_name
	FROM employees e
	INNER JOIN employees m
	ON e.manager_id=m.employee_id

4.8.4 外连接

应用场景 用于查询一个表中,另一个表中没有的记录
特点:

  1. 外连接的查询结果为主表中的所有记录
    如果从表中有和他匹配的,则显示匹配的值
    如果从表中没有他的匹配的 则显示null
    外连接查询结果=内连接结果+主表中有而从表中没有的记录
  2. 左外连接 LEFT JOIN 左边的是主表
    右外连接 RIGHT JOIN 右边的是主表
  3. 左外和右外交换两个表的顺序,可以实现同样的效果
  4. 全外连接=内连接的结果 表一有表二没有+表二有表一没有
  • 查询男朋友 不在男神表的女神名
    SELECT b.name,bo.*
    from beauty b
    LEFT OUTER JOIN boys bo
    ON b.boyfriend_id=bo.id
    WHERE bo.id IS NULL
    
    查询那个部门没有员工
  • 左外
    SELECT d.department_id,d.department_name
    FROM departments d
    LEFT JOIN employees e
    ON d.department_id=e.department_id
    WHERE e.employee_id IS NULL
    
  • 全外连接(mysql 不支持)
    USE girls;
    SELECT beauty.*,boys.*
    FROM beauty b
    FULL OUTER JOIN boys
    ON beauty.boyfriend_id = boys.'id';
    
  • 交叉连接(相当于是笛卡尔积全集)
     SELECT b.*,bo.*
     FROM beauty b
     CROSS JOIN boys bo
    
    数据库 (基础数据库知识 )_第11张图片数据库 (基础数据库知识 )_第12张图片

4.9 子查询

含义:
出现在其他语句中的select语句,称为只查询或内查询
外部的查询语句,称为主查询或外查询

分类:
按子查询出现的位置

  • select后面
    仅仅支持标量子查询
  • from后面
    支持表子查询
  • where或having后面
    标量子查询
    列子查询
    行子查询
  • exists 后面(相关子查询)
    表子查询
    按结果类的行列数不同
标量子查询 (结果集只有一行一列)
列子查询 (结果集只有一列多行)
行子查询 (结果集有一行多列)
表子查询 (结果集一般为多行多列)

*/
一.重点:where 或having 后面

特点:
子查询放在小括号内
子查询一般放在条件的右侧
标量子查询一般搭配着当行操作符使用
> < >= <= = <>
列子查询 一般搭配多行操作符使用
in any/some ALL

  1. 标量子查询(单行子查询)
    注:查出来的数据只有一条
    例1 谁的工资比Abel高
SELECT last_name,salary
FROM employees
WHERE salary>(select salary 
FROM employees
where last_name = 'Abel')

例二: 返回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) 
&& salary >
(SELECT salary 
FROM employees
WHERE employee_id=143);

例三:返回公司工资最少的员工的last_name job_id salarly

SELECT last_name ,job_id,salary 
from employees
 WHERE salary=
 (SELECT MIN(salary) 
 FROM employees);

例四:查询最低工资大于50号部门最低工资的部门id 和其最低工资

   SELECT MIN(salary)
   from  employees
   WHERE department_id =50

SELECT department_id ,MIN(salary) 
FROM employees 
GROUP BY department_id
HAVING MIN(salary)> 
(SELECT MIN(salary) 
from  employees
WHERE department_id =50)
ORDER BY MIN(salary) ASC
  1. 列子查询(多行子查询)
    数据库 (基础数据库知识 )_第13张图片
  2. 行子查询 (多列多行)
    案例:查询员工编号最小并且工资最高的员工信息
SELECT MIN(employee_id)
FROM employees

SELECT MAX(salary ) 
FROM employees

SELECT * 
from employees 
WHERE employee_id=
(SELECT MIN(employee_id) 
FROM employees) 
and 
salary =
(SELECT MAX(salary )
FROM employees)

进化:(这个是有局限性的  所以用的比较少)
SELECT *
FROM employees
WHERE (employee_id,salary) =
(SELECT MIN(employee_id),MAX(salary) 
FROM employees )

二. select后面
案例 查询每个部门的员工个数

select count(*),employees.*
FROM employees GROUP BY department_id

SELECT d.*,(SELECT COUNT(*) FROM employees e WHERE e.department_id=d.department_id) 个数
FROM departments d;

三 from 后面
案例 查询每个部门的平均工资的工资等级

SELECT avg(salary),department_id 
FROM employees
GROUP BY department_id

SELECT *FROM job_grades;

SELECT ag_dep.*,g.grade_level
FROM (SELECT avg(salary) ag,department_id 
FROM employees
GROUP BY department_id) ag_dep
INNER JOIN job_grades g
ON ag_dep.ag BETWEEN lowest_sal and highest_sal

四 exists 是否存在 后面(也就是相关子查询)

select EXISTS
(SELECT employee_id
 from employees)

4.10 分页查询

  • 应用场景:当要显示的数据 一页显示不全 需要分页提交sql请求
  • 语法:
   SELECT  查询列表
	 from 表
	 【JOIN type JOIN2ON 连接条件 
	 where 筛选条件
	 GROUP BY 分组数据
	 HAVING 分组后的筛选
	 ORDER BY 排序字段
	 LIMIT OFFSET,size
	 page-1  * size
  • OFFSET 要显示的条目的起始索引(起始索引从0 开始)
  • size 要显示的条目个数
  • 特点:
  1. limit 语句放在查询语句的最后
  2. 要显示的页数 page 每页的条目数size
 	 SELECT *from employees LIMIT 11,1

4.11联合查询

union 联合 合并 将多条查询语句的结果合并成一个结果

语法:
查询语句1
UNION
查询语句2
UNION

特点:

1. 要求多表查询语句的查询列表是一致的
2. 要求多条查询语句的查的每一列的类型和熟悉怒最好一致
3. union关键字默认去重 ,如果使用union all 可以包含重复项

查询部门编号》90或邮箱包含a的员工信息

SELECT *
FROM employees
WHERE email LIKE '%a%'
UNION 
SELECT * 
FROM employees
WHERE department_id >90

查询总算完了 下来是插入

5.DML语言 (数据操作语言)

  • 插入: insert
  • 修改:update
  • 删除:DELETE

5.1 插入语句

方式一:
语法:
INSERT INTO 表名(列名,…)
VALUES (值1,…);

SELECT *from beauty;


INSERT INTO beauty
        (id,NAME,sex,borndate,phone,photo,boyfriend_id) 
  VALUES(13,"tjk","男", '1990-4-23','19998888888',NULL,NULL);

注意:

  1. 如果遇到值为空的数据 可以不写那一列或者将该列设置为null
  2. 列的顺序可以对调 列的个数和值得个数必须一致
  3. 可以省略列名 默认所有列 而且列的顺序必须和表中列的顺序一致 可以空的值为空的话必须写null

方式二:
语法:

   INSERT into 表名
	    set 列名= 值,
			set 列名= 值,
方式1 支持多行同时插入 方式2 不支持
方式1 支持子查询 方式2 不支持

5.2 修改语句

  1. 修改单表的记录
    语法
    UPDATE 表名
    set 列=新值 , 列=新值…
    WHERE 筛选条件
  2. 修改多表的记录
    语法:
    sql92语法:
	      UPDATE1,表2 
				SET=WHERE 连接条件
				and 筛选条件

sql 99语法:

		    UPDATE1 别名
				INNER /LEFT /RIGHT JOIN2 别名
				ON 连接条件
				SET=值,
				SET=WHERE 筛选条件

5.3 删除语句

  • 方式一:单表删除
    DELETE
    语法: DELETE FROM 表名 where 筛选条件
  • 方式二: 多表的删除
    sql92
    DELETE1的别名,表二的别名
		FROM1  别名,表二 别名
		where 连接条件
		AND 筛选条件

sql99

	DELETE1 的别名,表2的别名
	from1 别名
	INNER /LEFT /right  JOIN2 别名 
								ON 连接条件

TRUNCATE (后面不能跟条件语句 所以是删除全表的数据的时候)
语法 TRUNCATE table 表名

- DELETE 语句和 TRUNCATE 语句的区别
1. delete 可以加where条件
2. TRUNCATE 删除 效率高一丢丢
如果用delete删除后 在插入语句 自增长列的值从断点开始
而 truncate 删除后 在插入数据 自增长列的值从1 开始
truncate 删除没有返回值 但是delete 删除有返回值
TRUNCATE 删除不能回滚 但是delete 删除可以回滚

6. DDL语言 (数据定义语言)

数据定义语言
库和表的管理

  • 一. 库的管理
    创建 修改 删除
  • 二. 表的管理
    创建 修改 删除
创建: create
修改: alter
删除: drop

6.1 库的管理

  1. 库的创建
    语法:
   create DATABASE 库名;
  1. 库的修改 (一般不进行修改 如果修改可能会造成数据库失败)
RENAME DATABASE books to 新库名

更改库的字符集

ALTER DATABASE books CHARACTER set  gbk
  1. 库的删除
DROP DATABASE IF EXISTS books

6.2 表的操作

  • 创建表
    CREATE TABLE 表名 (
    列名 类型 (位数) 约束,
    列名 类型 (位数) 约束,
    列名 类型 (位数) 约束,

创建表author

CREATE TABLE author
(  id INT,
   au_name VARCHAR(20),
	 nation VARCHAR(10)
 );
 DESC author;

表的修改
ALTER TABLE 表名
add/DROP /MODIFY /change
COLUMN 列名 类型名 约束

1.修改列名
2.修改列的类型弧或约束
3.添加新列
4.修改表名
5.删除列

  • 修改列名:
ALTER TABLE book 
CHANGE COLUMN 
publishdate pubDate DATETIME;
  • 修改列的类型
ALTER TABLE book
 MODIFY pubDate int ;
 
DESC book
  • 添加新列
ALTER TABLE author 
ADD COLUMN 
annual DOUBLE;
  • 删除列
ALTER TABLE author
 DROP COLUMN 
 annual;
  • 修改表名
ALTER TABLE author 
RENAME TO book_author;
  • 表的删除
    DROP TABLE if EXISTS book_author;
    SHOW TABLE 
  • 表的复制
    仅仅复制表的结构
	 CREATE TABLE author1
	  LIKE author;
  • 复制表的结构和数据
    CREATE TABLE author2 
    SELECT *FROM author
  • 只复制表的部分数据
	 CREATE table author3 
	 select
	 id, au_name
     from author
	 WHERE nation="chong "

6.3 数据类型

int 特点:

  1. 如果不设置无符号还是有符号,默认有符号,如果想设置无符号,需要添加
    UNSIGNED关键字
  2. 如果插入的数值超过了整型的范围,会报out of range 异常,并且插入临界值
  3. 如果不设置长度 会有默认的长度
    长度代表的是最大的宽度,如果不够会用o在左边填充,但是必须搭配ZEROFILL使用

浮点型
所选择的类型越简单越好 能保存数值的类型越小越好

char: 固定的字符串长度
varchar:可变长度的字符串

- 写法 M的意思 特点 空间的耗费 效率
char char() 最大的字符数 固定长度的字符 比较耗费
varchar varchar() 最大的字符数 可变长度的字符 比较节省

其它:
BINARY 和varbinary 用于保存较短的二进制
enum用于保存枚举 但是不区分大小写 并且长度不限
set 用于保存集合

6.4 时间类型

date 只有年月日
datatime 年月日 时分秒
TIMESTAMP
time 时分秒
year 年

  1. TIMESTAMP 支持的时间范围较小
    dateteme 取值范围大
  2. TIMESTAMP 和实际时区有关 更能反映实际的日期 而 datetime则只能反映出插入时的当地时区
  3. TIMESTAMP 的属性受Mysql版本和sqlMode的影响很大

特点:

字节 范围 时区等的影响
datetime 8 1000-9999 不受
TIMESTAMP 4 1970–2030

6.5 常见约束

  • 常见约束
    含义: 一种限制 用于限制表中的数据 为了保证表中的数据的准确好可靠性

  • 分类 六大约束

  1. not null 非空 用于保证该字段的值不能为空
    比如姓名 学号等
  2. DEFAULT 默认 用于保证该字段有默认值
    比如性别
  3. PRIMARY key 主键 用于保证该字段的值具有唯一性,并且非空
    比如学号 员工编号等
  4. UNIQUE 唯一,用于保证该字段的值具有唯一性 可以为空
    比如座位号
  5. CHECK 检查约束[mysql中不支持]
    比如 年龄 性别
  6. FOREIGN key 外键 用于限制两个表的关系 用于保证该字段的值必须来自于主表的关联列的值
    在从表添加外键约束 用于引用主表中某列的值
  • 添加约束的时机
    1. 创建表时
    2. 修改表时
      约束的添加分类
      - 列级约束:
      六大约束语法上都支持,但外键约束没有效果
      - 表级约束:
      除了非空 默认 其他的都支持

CREATE TABLE 表名(
字段名 字段类型 约束
字段名 字段类型 约束

创建表时添加约束
1.添加列级约束

CREATE table stuinfo(
    id  int PRIMARY key,#主键
		stuName VARCHAR(20)  not NULL,#非空
		gender char(1) CHECK(gender='男' or gender ='女'),#检查
		seat int UNIQUE,#唯一
		age int DEFAULT 18,
    majorId int  REFERENCES major(id)#外键
)
CREATE TABLE major(
    id  int PRIMARY key,
		majorName VARCHAR(20)

)
  • 添加表级约束
    DROP TABLE if EXISTS stuinfo
CREATE table stuinfo(
    id  int,
		stuName VARCHAR(20),
		gender char(1),
		seat int ,
		age int ,
    majorId int ,
		CONSTRAINT pk PRIMARY KEY(id),
		CONSTRAINT uq UNIQUE(seat),
		CONSTRAINT ck CHECK(gender = '男' or gender='女'), #检查
		CONSTRAINT fk_stuinfo_major FOREIGN key(majorid) REFERENCES major(id)#外键
)

主键和唯一的大对比

保证唯一性 是否允许为空 一表中可以有多个
主键 至多有一个
唯一 可以有多个

外键的特点:
1.要求在从表这只外键关系
2.从表的外键列的类型好主表的关联列的类型要求一致或兼容,名称无要求
3.主表的关联类必须是一个key(主键或 唯一 )

  • 修改表时添加约束
  1. 添加非空约束
alert table stuinfo MODIFY COLUMN stuname VARCHAR(20) not NULL
  1. 添加默认约束
alter TABLE stuinfo MODIFY COLUMN age int DEFAULT 18

3.添加主键

ALTER TABLE stuinfo MODIFY COLUMN id int PRIMARY KEY
ALTER TABLE stuinfo ADD PRIMARY KEY(id);

4.添加唯一键

ALTER table stuinfo MODIFY COLUMN seat int UNIQUE
ALTER TABLE stuinfo ADD UNIQUE (seat)

5.添加外键

ALTER TABLE stuinfo add CONSTRAINT fk_stuinfo_major FOREIGN key(majorid) REFERENCES major(id)
  • 修改表时删除约束
    删除非空约束
ALTER table stuinfo MODIFY COLUMN stuname VARCHAR(20) NULL

删除默认约束

ALTER table stuinfo MODIFY COLUMN age int 

删除主键

alter TABLE stuinfo DROP PRIMARY key

删除唯一

ALTER TABLE stuinfo drop INDEX seat

删除外键

ALTER TABLE stuinfo DROP FOREIGN key fx_stuinfo_major

6.6 标识列

  • 又称为自增长列
    可以不用手动的插入值 系统提供默认的序列

特点:

  1. 标识列必须和主键搭配? 不一定 但是必须是一个key
  2. 一个表中可以有多个标识列吗 不行
  3. 标识列的类型只能是数值类型的

一.创建表时设置标识列

CREATE TABLE tab_identity(
    id int PRIMARY key AUTO_INCREMENT,
		NAME VARCHAR(20)
)

INSERT INTO tab_identity VALUES(null,'join')
SELECT *from tab_identity

二. 修改表时设置标识列

ALTER TABLE tab_identity MODIFY COLUMN id int PRIMARY KEY AUTO_INCREMENT

三. 修改表时删除标识列

ALTER TABLE tab_identity MODIFY COLUMN id int 

你可能感兴趣的:(数据库)