Mysql基础
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Mysql基础,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含30663字,纯文字阅读大概需要44分钟。
内容图文
Mysql学习笔记
一、数据库的基本概念
- DB 数据库(database):存储数据的“仓库”,它保存了一系列有组织的数据。
- DBMS 数据库管理系统 (Database ManagementSystem)。数据库是通过DBMS创建和操作的容器。
- SQL 结构化查询语言 (Structure Query Language),专门用来和数据通信的语言。
SQL的优点
- 不是某个数据库供应商特有的专用语言,几乎所有DBMS都支持SQL
- 简单易学
- 虽然简单,但实际上是一种强有力的语言,灵活使用其语言元素,可以进行非常复杂和高级的操作。
数据库的特点
- 将数据放到表中,表再放到数据库中。
- 一个数据库可以有多张表,每个表都有一个名字,用来标识自己,表名具有唯一性。
- 表由列组成,我们也称为字段,所有表都是由一个或多个列组成的。
- 表中的数据是按行存储的。
Mysql 语法规范
- 不区分大小写,但建议关键字大写,表名、列名小写;
- 每条命令最好用分号结尾;
- 每条命令根据需要,可以进行缩进或换行;
- 注释
单行注释:#注释文字
单行注释:-- 注释文字
多行注释:/注释文字/
二、DQL语言
进阶一:基础查询
语法
select 查询列表 from 表名;
- 特点
查询列表可以是:表中的字段、常量值、表达式、函数
查询的结果是一个虚拟的表格
use employees;#查询前需要先打开数据库
#查询表中单个字段
select last_name from employee;
#查询表中多个字段
select last_name,salary,email from employees;
#查询表中所有字段
select * from employees;
查询常量值
select 100;
select 'john';
#查询表达式
select 100*98;
#查询函数
select version();
#起别名(便于理解;如果查询的字段有重名的情况,使用别名可以区分开来)
方式一:使用as
select 100*98 as 结果;
select last_name as 姓,first_name as 名 from employees;
方式二:使用空格
select last_name 姓,first_name 名 from employees;
#注:别名中有关键字等特殊符号,需要将别名用引号引起来
select salary as "out put" from employees;
#去重
#案例 查询员工表中涉及到的所有的部门编号
select distinct department_id from employees;
+号作用
# mysql中的+号,仅仅只有一个功能:运算符
select 100+90;两个操作数都为数值型,则做加法运算
select '100'+90; 只要其中一方为字符型,试图将字符型转换为数值型
如果转换成功,则继续做加法运算
select 'john'+90 如果转换失败,则将字符型数值转换为0
select null+90; 如果其中一方为null,则结果肯定为null
# 案例:查询员工名和员工姓连接成一个字段,并显示为 姓名
select concat(first_name,last_name) as 姓名 from employees;
#显示表结构
desc department;
进阶二:条件查询
select 查询列表 from 表名 where 筛选条件;
筛选条件分类:
- 按条件表达式筛选
条件运算符 > < = != <> >= <= - 按逻辑表达式筛选
逻辑运算符 and or not
作用:用于连接条件表达式 - 模糊查询
like
between and
in
is null
按条件表达式查询
#案例1 :查询工资>12000 的员工信息
select * from employees where salary>12000;
#案例2:查询部门编号不是90的员工姓名和部门编号
select
last_name,
department_id
from
employees
where
department_id != 90;
按逻辑表达式查询
# 案例1:查询工资在10000到20000之间的员工名、工资及奖金
select
last_name,
salary,
commission
from
employees
where
salary>=10000 and salary<=20000;
#案例2:查询部门编号不在90-110之间,或者工资高于15000的员工信息
select
*
from
employees
where
not(department_id>=90 and department_id<=110) or salary>=15000;
模糊查询
- like
特点:1.一般和通配符搭配使用
2. % 任意多个字符
3. _任意单个字符
#案例1:查询员工名中包含字符a的员工信息
select
*
from
employees
where
last_name like '%a%';
#案例2:查询员工名中第三个字符为n,第五个字符为m的员工名和工资
select
last_name,
salary
from
employees
where
last_name like '__n_m%';
#案例3:查询员工名中第二个字符为_的员工名
select
last_name
from
employees
where
last_name like '_\_%';
- between and
特点:1.使用between and 可以简化查询语句
2.包含临界值
3.两个临界值不要调换顺序
#案例:查询员工编号在100到200之间的员工信息
select
*
from
employees
where
employee_id>=100 and employee_id<=200;
---------------------------------------------------------------
select
*
from
employees
where
employee_id between 100 and 200;
- in
含义:判断某字段的值是否属于in列表中的某一项
特点:1. 使用in比使用or提高了语句简洁度
2. in列表的值类型必须统一或者兼容
#案例:查询员工的工种编号是vp,vn,vc的员工姓名和工种编号
select
last_name,
job_id
from
employees
where
job_id = 'vp' or job_id = 'vn' or job_id = 'vc';
---------------------------------------------------
select
last_name,
job_id
from
employees
where
job_id in ('vp','vn','vc');
- is null
1.= 或者<>不能用来判断null
2.is null 或者is not null可以进行判断
#案例:查询没有奖金的员工名和奖金率
select
last_name,
commission_pct
from
employees
where
commission_pct is null;
- 安全等于 <=>
#案例1:查询没有奖金的员工名和奖金率
select
last_name,
commission_pct
from
employees
where
commission_pct <=> null;
# 案例2:查询工资为12000的员工信息
select
*
from
employees
where
salary <=>12000;
is null pk <=>
- is null :仅仅可以判断null值,可读性较高,建议使用;
- <=> :既可以判断null值,又可以判断普通的数值,可读性较低。
进阶三:排序查询
#语法:
select 查询列表
from 表
(where 筛选条件)
order by 排序列表 (asc | desc)
- 特点:1.desc 降序排列
2. asc 升序排列 不写默认升序排列
3.order by 子句中可以支持单个字段、多个字段、表达式、函数、别名
4.order by 一般放在查询语句的最后面,limit子句除外
# 案例1:查询部门编号大于90 的员工信息,按照入职时间先后进行排列(添加了筛选条件)
select *
from employees
where department_id >=90
order by hiredate asc;
#案例2:按年薪的高低显示员工信息和年薪
select *,salary*12*(1+ifnull(commission_pct,0)) as 年薪
from employees
order by salary*12*(1+ifnull(commission_pct,0)) desc;
【按别名排序】
#案例3:按年薪的高低显示员工信息和年薪
select *,salary*12*(1+ifnull(commission_pct,0)) as 年薪
from employees
order by 年薪 desc;
【按函数排序】
# 案例4:按姓名的长度显示员工的姓名和工资
select length(last_name) 字节长度,last_name,salary
from employees
order by length(last_name) desc;
【按多个字段排序】
# 查询员工信息,先按照工资进行升序,再按照部门编号降序排列
select *
from employees
order by salary asc,employee_id desc;
进阶四:常见函数
- 概念:类似于Java中的方法,将一组逻辑语句封装在方法中,对外暴露方法名
- 好处:1.隐藏了实现细节 2.提高代码的重用性
调用函数:select 函数名(实参列表)【from 表】 - 特点:1.叫什么(函数名) 2.干什么(函数功能)
- 分类:1.单行函数 如 concat、length、ifnull
2.分组函数 做统计使用又称为统计函数、聚合函数、组函数
字符函数
- length 函数 获取参数值得字节个数
select length('john');
select length('张三丰hahahha')
#返回值 15 注 一个字母代表一个字节,一个汉字代表三个字节
- .concat 拼接字符串
select concat(first_name,'_',last_name)
from employees;
- upper、lower
select upper('john');
# 示例 将姓大写,名小写,并进行拼接
select concat(upper(last_name),lower(first_name)) as 姓名
from employees;
- substr substring
注意:索引从1开始
#截取从指定索引处后面的所有字符
select substr('李莫愁爱上了陆展元',7);
#截取从指定索引处的字符长度的字符
select substr('李莫愁爱上了陆展元',1,3);
#案例:姓名中首字母大写,其它字符小写然后用_拼接,显示出来
select concat(upper(substr(last_name,1,1),'_'lower(substr(last_name,2))) as 姓名
from employees;
- instr
#返回子串第一次出现的索引,如果找不到返回0
select instr('杨不悔爱上了殷六侠','殷六侠');
- trim
#删除字符两端的空格或字符
select trim(' 张翠山 ') as output;
select trim('a','aaaaa张翠山aaaa') as putputl
- lpad
#用指定的字符实现左侧填充指定的长度
select lpad('殷素素',10,*) as output;
- rpad
#用指定的字符实现左侧填充指定的长度
select rpad('殷素素',12,ab) as output;
- replace
#用指定字符去替换字符中的指定字符
select replace('周芷若爱上了张无忌','周芷若','张无忌') as output;
数学函数
- round 四舍五入
select round(1.57);
select round(1.567,2);
- ceil 向上取整
# 返回大于该参数的最小整数
select ceil(1.002);
- floor 向下取整
select floor(9.99);
- truncate 截断 截断并保留小数点后指定位数
select truncate(1.5888,1);
#返回值为1.5,不进行四舍五入,进行截断
- mod 取余
select mod(10,3);
日期函数
- now 返回当前系统日期+时间
select now();
- curdate 返回系统当前日期,不包含时间
select curdate();
- curtime 返回当前时间,不包含日期
select curtime();
- 可以获取指定的部分,年year、月month、日day、小时hour、分minute、秒second
select year(now()) as 年;
select year('2020-1-20') as 年;
#返回月份的英文
select monthname(now()) as 月;
- str_to_date : 将日期格式的字符转换成指定格式的日期
select str_to_date('2020-2-1','%Y-%c-&d');
- date_format :将日期转换成字符
#查询有奖金的员工姓名和入职日期,日期显示格式为 xx月xx日 xx年
select last_name,date_format(hiredate,%m月%d日 %y年)
from employees
where employee_pct is not null;
其它函数
# 查看版本号
select version();
#查看有哪些数据库
select databases();
#查看用户
select user();
流程控制函数
- if 函数 类似if else的效果
select last_name,salary,if(salary is null,'没工资,呵呵','有工资,嘻嘻')
from employees;
进阶五:分组函数
- 功能:用作统计使用,又称为聚合函数或统计函数或函数组。
- 分类:sum 求和、avg 平均值 、max 最大值、min 最小值、count 计数
- 简单的使用:
select sum(salary) from employees;
select max(salary) from employees;
select min(salary) from employees;
select avg(salary) from employees;
select count(salary) from employees;
select sum(salary) 总工资,max(salary) 最高,avg(salary) 平均值
from employees;
- 参数支持的类型
1、sum、avg一般用于处理数值型
2、 max、min、count可以处理任何类型
3、可以和distinct搭配使用实现去重
4、以上分组函数都忽略null值 - count函数的详细介绍
select count(salary) from employees;
select count(*) from employees;
select count(1) from employees;
select count('崔霞') from employees;
- count函数的单独介绍
一般使用count(*)用作统计行数 - 和分组函数一同查询的字段要求是group by后的字段
进阶六:分组查询
- 语法
select 分组函数,列(要求出现在group by的后面)
from 表名
【where 筛选条件】
group by 分组的列表
【order by 子句】
注:查询列表比较特殊,要求是分组函数和group by后出现的字段
特点:分组查询中的筛选条件分为两类
1.分组前筛选 数据源为原始表 , 位置在group by子句的前面 , 关键字为where
2.分组后筛选 数据源为分组后的结果集 ,位置在group by子句的后面 , 关键字为having
- 分组函数做条件肯定是放在having子句中
- 能用分组前筛选的,优先使用分组前筛选
- group by 子句支持单个字段分组,多个字段分组(多个字段之间用逗号隔开没有顺序要求),表达式或者函数(用的较少)
- 也可以添加排序(放在整个的分组查询的最后)
#简单的分组查询
# 查询每个工种的最高工资
select max(salary),job_id
from employees
group by job_id;
#查询每个位置上的部门个数
select count(*),location_id
from employees
group by location_id;
#查询邮箱中包含字母a,每个部门的平均工资
select avg(salary),department_id
from employees
where email like '%a%
group by department_id;
#查询每个领导手下员工的最高工资
select max(salary),manager_id
from employees
where commission_pct is not null
group by manager_id;
- 添加分组后的筛选条件(having子句的使用)
#案例1:查询哪个部门的员工数>2
select count(*),department_id
from employees
group by department_id
having count(*)>2;
案例2:查询每个工种有奖金的员工的最高工资>12000的工种编号和最高工资
select max(salary),job_id
from employees
where commission_pct is not null
group by job_id
having max(salary)>12000;
#案例3:查询每个领导编号大于102的员工的最低工资大于5000的领导编号和最低工资
select min(salary),manager_id
from employees
where manager_id>102
group by manager_id
having min(salary)>5000;
- 按表达式或函数分组
# 案例: 按员工姓名的长度分组,查询每一组的员工个数,筛选员工个数>5的有哪些
select count(*)
from employees
group by length(last_name)
having count(last_name);
- 按多个字段分组
#查询每个部门每个工种的员工的平均工资
select avg(salary),department_id,job_id
from employees
group by department_id,job_id;
- 添加排序
#查询每个部门每个工种的员工的平均工资,并筛选出平均工资大于10000的从高到低排序
select avg(salary).department_id,job_id
from employees
where department_id is not null
group by department_id,job_id
having avg(salary)>10000
order by avg(salary) desc;
- 练习
# 查询各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;
# 查询员工最高工资和最低工资的差距(difference)
select max(salary)-min(salary) difference
from employees;
#查询各个管理者手下员工的最低工资,其中最低工资不能低于6000,没有管理者的员工不计算在内
select min(salary),manager_id
from employeers
where manager_id is not null
group by manager_id
having min(salary)>=6000;
#查询所有部门的编号、员工数量和工资平均值,并按平均工资降序
select department_id,count(*),avg(salary)
from employees
group by department_id
order by avg(salary) desc;
#选择具有各个job_id的员工人数
select count(*) 个数,job_id
from employees
group by job_id;
进阶七:连接查询
- 含义:又称多表查询,当需要用到两个表的时候
- 笛卡尔乘积现象:表1有m行,表2有n行,结果=m*n行
如何避免:添加有效的连接条件 - 分类:按年代分类 sql92标准(仅仅支持内连接)、sql99标准(推荐使用)
按功能分类:内连接(分为等值连接、非等值连接、自连接)、外连接(左外连接、右外连接、全外连接)、交叉连接 - 等值连接
特点:多表等值连接的结果为多表的交集部分;
n表连接至少需要n-1个连接条件;
多表的顺序没有要求;
一般需要为表起别名;
可以搭配前面介绍的所有子句使用,比如排序、分组、筛选
#查询员工名和对应的部门名
select last_name,department_name
from employees,departments
where employees.'department_id'=departments.'department_id';
- 为表起别名
好处:提高语句的简洁度,区分多个重名的字段
如果为表起了别名,则查询的字段就不能使用原来的表名去限定
#查询员工名、工种号、工种名
select e.last_name ,e.job_id,j.job_title
from employees e,jobs j
where e.'job_id'=j,'job_id';
- 可以加筛选
#查询有奖金的员工名、部门名
select last_name,department_name
from employees e,department f
where e.'department_id'=f.'department_id'
and e.'commission_pct' is not null;
#查询城市名中第二个字符为o的部门名和城市名
select department_name,city
from departments d,location l
where d.'location_id' = l.'location_id'
and city like '_o%';
- 可以加分组
#查询每个城市的部门个数
select count(*) 个数
from departments d,locations l
where d.'location_id' = l.'location_id'
group by city;
#查询有奖金的每个部门的部门名和部门的领导编号和该部门的最低工资
select department_name,d.'manager_id',min(salary)
from department d,employees e
where d.'department_id' = e.'department_id'
and commission_pct is not null
group by department_name,d.'manager_id';
- 可以加排序
#查询每个工种的工种名和员工的个数,并且按照员工个数降序
select job_title,count(*)
from employees e,jobs j
where e.'job_id' = j.'job_id'
group by job_title
order by count(*) desc;
- 实现三表连接
#查询员工名、部门名和所在城市
select last_name,department_name,city
from employees e,department d,location l
where e.'department_id' = d.'department_id' and d.'location_id' = l.'location_id';
- 非等值连接
# 查询员工的工资和工资级别
select salary,grade_level
from employees e,job_grade g
where salary between g.'lowest_sal' and g.'highest_sal';
- 练习
#显示员工表的最大工资、工资平均值
select max(salary),avg(salary) from employees;
# 查询员工表的employees_id,job_id,last_name,按department_id 降序,salary升序
select employees_id,job_id,last_name from employees order by department_id desc,salary asc;
#查询员工表的job_id中包含a和e,并且a在e的前面
select job_id from employeees where job_id like %a%e%;
#显示当前日期、以及去前后空格,截取子字符串函数
select now();
select trim();
select substr();
- sql99语法
- 内连接
- 外连接
- 语法
#语法
select 查询列表
from 表1 别名 【连接类型】
join 表2 别名
on 连接条件
【where 筛选条件】
【group by 分组】
【order by 排序列表】
- 分类
内连接:inner
外连接 :左外 left outer、右外 right outer 、全外 full outer
交叉连接 cross - 内连接
#语法
select 查询列表
from 表1 别名
inner join 表2 别名
on 连接条件
- 分类: 等值、非等值、自连接
#等值连接
#案例1:查询员工名、部门名
select last_name,department_name
from employees e
inner join departments d
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;
#案例4:查询哪个部门的员工个数大于3的部门名和员工个数,并按个数降序【添加排序】
select count(*),department_name
from employees e
inner join department d
on e.'department_id'=d.'department_id'
group by department_name
having count(*)>3
order by count(*) desc;
#案例5:查询员工名、部门名、工种名,并按部门名降序【添加三表排序】
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;
- 特点:添加排序 、分组筛选;inner可以省略;筛选条件放在where后面,连接条件放在on后面,提高分离性,便于阅读;inner join连接和sql92语法中的等值连接效果是一样的,都是查询多表的交集。
- 非等值连接
#查询员工工资级别
select salary,grade_level
from employees e
join job_grades g
on e.'salary'between g.'lowest_sal' and g.'higest_sal';
#查询工资级别的个数>20的个数,并且按照工资级别降序
select count(*),grade_level
from employees e
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
- 外连接
应用场景:用于查询一个表中有,另一个表中没有的记录
进阶八:子查询
- 含义:出现在其它语句中的select语句,称为子查询或内查询;外部的查询语句,称为主查询或外查询
- 分类:按子查询出现的位置:select后面(仅仅支持标量子查询)、from后面(支持表子查询)、where或having后面(支持标量子查询、列子查询、行子查询)、exists后面(相关子查询、支持表子查询)
- 按结果集的行列数不同 :标量子查询(结果集只有一行一列)、列子查询(结果集只有一列多行)、行子查询(结果集有一行多列)、表子查询(结果集一般为多行多列)
- where 或having后面
1.标量子查询(单行子查询)
2.列子查询(多行子查询)
3.行子查询(多列多行)
特点:1.子查询都或放在小括号内;2.子查询一般放在条件的右侧;3.标量子查询,一般搭配着单行操作符使用 > < >= <= = <>
列子查询,一般搭配着多行操作符使用 in、any/some、all
4、子查询的执行优先于主查询执行,主查询的条件用到了子查询的结果 - 标量子查询
#案例1 :查询谁的工资比abel高?
select *
from emoloyees
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
);
#案例3:返回公司工资最少的员工 last_name
select last_name
from employees
where salary=(
select min(salary)
from employees
);
#案例4:查询最低工资大于50号部门最低工资的部门id和其最低工资
select min(salary),department_id
from employees
group by department_id
having min(salary)>(
select min(salary)
from employees
where department_id =50
);
- 列子查询(多行子查询)
#案例1:返回location_id是1400或1700的部门中 所有员工姓名
select last_name
from employees
where department_id in(
select distinct department_id
from departments
where location_id in(1400,1700)
);
#案例2:返回其它工种中job_id 为‘IT_prog’工种任一工资都低的员工的员工号、姓名、工资
select last_name,employees_id,salary
from employees
where salary<any(
select salary
from employees
where job_id = 'IT_PROG') and
job_id<>'IT_PROG';
#案例3:返回其它部门中job_id 为‘IT_PROG’部门所有工资都低的员工的员工名、姓名以及salary
select last_name,employees_id,salary
from employees
where salary<all(
select salary
from employees
where job_id = 'IT_PROG') and
job_id<>'IT_PROG';
- 行子查询
#查询员工编号最小并且工资最高的员工信息
select *
from employees
where (employees_id,salary) = (
select min(employees_id),max(salary)
from employees
);
- select后面的子查询
- from 后面的子查询
将子查询结果充当一张表,要求必须起别名
#案例:查询每个部门的平均工资的工资等级
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.agbetween lowest_sal and highest_sal;
- exists后面(相关子查询)
语法:exists(完整的查询语句)
结果为1或0 - 练习
#1、查询和zlotkey相同部门的员工姓名和工资
select last_name,salary
from employees
where department_id = (
select department_id
from employees
where last_name = 'zlotkey'
);
#2、查询工资比公司平均工资高的员工的员工号、姓名和工资
select employees_id,last_name,salary
from employees
where salary>(
select avg(salary)
from employees
);
#3、查询各部门中工资比本部门平均工资高的员工的员工号、姓名和工资
select employee_id,last_name,salary
from employees e
inner join (
select avg(salary) ag,department_id
from employees
group by department_id
) ag_dep
on e,department_id = ag_dep.department_id
where salary>ag_dep.ag;
#4、查询姓名中包含字母u的员工在相同部门的员工的员工号和姓名
select employees_id,last_name
from employees
where department_id in(
select department_id
from employees
where last_name like %u%
);
#5、查询在部门的location_id为1700的部门工作的员工的员工号
select employee_id
from employees
where department_id = any(
select department_id
from departments
where location_id = 1700
);
#6、查询管理者是King的员工姓名和工资
select last_name,salary
from employees
where manager_id in(
select employee_id
from employees
where last_name = 'king'
#7、查询工资最高的员工的姓名,要求要求first_name 和last_name显示为一列,列名为姓.名
select concat(first_name,last_name) “姓.名”
from employees
where salary=(
select max(salary)
from employees
);
进阶九:分页查询
- 应用场景:当要显示的数据,一页显示不全,需要分页提交sql请求
- 语法结构:select 查询列表
from 表
【join type join 表2
on 连接条件
where 筛选条件
group by 分组字段
having 分组后的筛选
order by 排序的字段
】
limit【offset】 size
offset:要显示条目的起始索引(起始索引从0开始)
size:要显示的条目个数 - 特点:1、limit语句放在查询语句的最后
2、公示:要显示的页数 page ,每页的条目数 size
select 查询列表
from 表
limit (page-1)*size,size
#案例1:查询前五条员工信息
select * from employees limit 0,5;
#案例2:查询第11-25条的员工信息
select * from employees limit 10,15;
#案例3:有奖金的员工信息,并且工资较高的前十名显示出来
select *
from employees
where commission_pct is not null
order by salary desc
limit 10;
- 截止目前,查询语句中涉及的所有关键字,以及执行先后顺序
select 查询列表 7
from 表 1
连接类型 join 表2 2
on 连接条件 3
where 筛选条件 4
group by 分组字段 5
having 分组后筛选 6
order by 排序 8
limit 起始索引,显示条目数 9
- 练习
#1、查询工资最低的员工信息:last_name,salary
select last_name,salary
from employees
where salary=(
select min(salary)
from employees
);
#2、查询平均工资最低的部门信息
select *
from departments
where department_id = (
select department_id
from employees
group by department_id
order by avg(salary)
limit 1
);
#3、查询平均工资最低的部门信息和该部门的平均工资
select d.*,avg
from department d
join (
select avg(salary) avg,department_id
from employees
group by department_id
order by avg(salary)
limit 1
) ag_dep
on d.'department_id'=ag_dep.'department_id'
#4、查询平均工资最高的job信息
select *
from jobs
where job_id=(
select job_id
from employees
group by job_id
order by avg(salary) desc
limit 1
);
#5、查询平均工资高于公司平均工资的部门有哪些
select avg(salary),department_id
from employees
group by department_id
having avg(salary)>(
select avg(salary)
from employees
);
#6、查询出公司中所有manager的详细信息
select *
from employees
where employee_id = any(
select distinct manager_id
from employees
);
#7、各个部门中最高工资中最低的那个部门的最低工资是多少
select min(salary)
from employees
where department_id=(
select department_id
from employees
group by department_id
order by max(salary)
limit 1
);
#8、查询平均工资最高的部门的manager的详细信息:
last_name,department_id,email,salary
select last_name,department_id,email,salary
from employees
inner join
departments d
on d.manager_id = e.employees_id
where d.department_id= (
select department_id
from employees
group by department_id
order by avg(salary) desc
limit 1
);
进阶十:联合查询
- union 联合 合并:将多条查询语句的结果合并成一个结果
- 语法:
查询语句1
union
查询语句2
union
… - 应用场景:要查询的结果来自多个表,且多个表没有连接关系, 但查询的信息一致时
- 特点:1、要求多条查询的查询列数一致时
2、要求多条查询语句的查询的每一列的类型和顺序最好一致
3、union关键字默认去重,如果使用union all可以包含重复项
三、DML语言
数据操作语言
- 插入:insert
- 修改:update
- 删除:delete
插入语句
- 语法:insert into 表名(列名…)values(值1,…)
- 注意:1、插入的值得类型要与列的类型一致或兼容
insert into beauty(id,name,sex,borndate,phone,photo,boyfriend_id)
values(13,'唐艺昕','女','1990-4-23','18912345667',null,12);
2、不可以为null的列必须插入值,可以为null的列如何插入值?
方式一:
insert into beauty(id,name,sex,borndate,phone,photo,boyfriend_id)
values(13,'唐艺昕','女','1990-4-23','18912345667',null,12)
方式二:
insert into beauty(id,name,sex,borndate,phone,boyfriend_id)
values(13,'唐艺昕','女','1990-4-23','18912345667',12);
3、列的顺序是否可以调换?
insert into brauty(name,id,phone,sex) 可以调换列的顺序
values('蒋欣',16,'183333333','女');
4、列数和值得个数必须一致
5、可以省略列名,默认所有列,而且列的顺序和表中列的顺序一致
insert into beauty
values(18,'张飞','男',null,'119',null,null);
- 方式二
语法:insert into 表名 set 列名=值,列名=值,…
insert into beauty
set id=19,name='刘涛',phone='111';
- 两种方式大pk
1、方式一支持插入多行,方式二不支持
insert into beauty(id,name,sex,borndate,phone,boyfriend_id)
values(23,'唐艺昕1','女','1990-4-23','18912345667',12),
(24,'唐艺昕2','女','1990-4-23','18912345667',12),
(25,'唐艺昕3','女','1990-4-23','18912345667',12);
2、方式一支持子查询,方式二不支持
二、修改语句
1、修改单表的记录
语法:
update 表名
set 列=新值,列=新值,…
where 筛选条件
#案例1:修改beauty表中姓唐的女神的电话为1388888
update beauty set iphone='1388888'
where name like '唐%';
#案例2:修改boys表中ID为2的名称为张飞,魅力值为10
update boys set name='张飞',usercp=10
where id=2;
2、修改多表的记录
语法:
update 表1 别名
inner|left|right join 表2 别名
on 连接条件
set 列=值,…
where 筛选条件;
#案例:修改张无忌的女朋友的电话为119
update boy bo
inner join beauty b
on b.'id'=bo.'boyfriendid'
set phone=119
where bo.'boyname'='张无忌';
三、删除语句
方式一:delete
1、单表删除
语法:delete from 表名 where 筛选条件;
#案例:删除手机号一9结尾的女神信息
delete from beauty where phone like '%9';
2、多表删除
方式二:truncate
语法:truncate table 表名;
#案例1:删除张无忌的女朋友的信息
delete b
from beauty b
inner join boys bo
on b.'boyfriends_id'=bo.'id'
where bo.'boyname'='张无忌';
#案例2:删除黄晓明的信息和他女朋友的信息
delete b,bo
from boys bo
inner join beauty b on b.'boyfriend_id'=bo.'id'
where bo.'boyname'='黄晓明';
四、DDL语言
数据定义语言
库和表的管理
- 库的管理
创建、修改、删除 - 表的管理
创建、修改、删除
创建:create
修改:alter
删除:drop
库的管理
- 库的创建
语法:create database [if not exists] 库名;
create database chen;
- 库的修改
rename database books to 新库名;
- 更改库的字符集
alter database books character set gbk;
- 库的删除
drop database books;
表的管理
- 表的创建
create table 表名(
列名 列的类型 【(长度) 约束】,
列名 列的类型 【(长度) 约束】,
列名 列的类型 【(长度) 约束】,
列名 列的类型 【(长度) 约束】,
...
列名 列的类型 【(长度) 约束】
);
- 表的修改
1、修改列名
alter table book change column publishdate pubdate datetime;
2、修改列的类型或约束
alter table book modify column pubdate timestamp;
3、添加新列
alter table book add colunmn annual double;
4、删除列
alter table book drop column annual;
5、修改表名
alter table book rename to chen_book;
- 表的删除
drop table book;
show tables;#查看当前库的表
#通用的写法
drop database if exists 旧库名;
create database 新库名;
drop table if exists 旧表名;
create table 新表名();
- 表的复制
#仅仅复制表的结构
create table chen like book;
#复制表的结构+数据
create table chen1
select * from book;
#只复制部分数据
create table chen3
select id,name
from book
where country='china';
#仅仅复制某些字段
create table chen4
select ID
from book
where 0;
#跨数据库插入数据
create table chen5
select department_id,department_name
from myemployees.departments;
常见的数据类型
- 数值型
1、整形
tinyint、smallint、mediumint、int/integer、bigint
特点:
如果不设置无符号还是有符号,默认是有符号,如果想设置无符号,需要添加unsigned;
如果插入的数值超出了整形的范围,会报out of range 异常,并且插入临界值;
如果不设置长度,会有默认的长度
2、小数
分类:浮点型float、定点型double
2.1 定点数
2.2 浮点数 - 字符型
1、较短的文本 :char(m)代表固定长度字符、varchar(m)代表可变字符;m代表最多字符数
2、较长的文本:text、blob(较长的二进制数据) - 日期型
分类:date 只保存日期、time只保存时间、year只保存年、datetime保存日期+时间、timestamp保存日期+时间(受时区影响)
常见约束
- 含义: 一种限制,用于限制表中的数据,为了保证表中的数据的准确和可靠性
- 分类:六大约束
not null :非空,为了保证该字段的值不能为空;
default:默认,用于保证该字段有默认值;
primary key:主键,用于保证该字段的值具有唯一性,并且非空;
unique:唯一,用于保证该字段的值具有唯一性,可以为空;
check:检查约束【mysql中不支持】;
foreign key:外键,用于限制两个表的关系的,用于保证该字段值必须来自主表的关联的值;在从表添加外键约束,用于引用主表某列的值;
添加约束的时机:1、创建表时;2、修改表时
约束的添加分类:1、列级约束:六大约束语法上都支持,但外键约束没有效果;2、表级约束:除了非空,默认,其它都支持
- 创建表时添加约束
1、添加列级约束
语法:直接在字段名和类型后面追加约束
use student;
create table stuinfo(
id int primary key,#主键
stuname varchar(20) not null,#非空
seat int default 18,#默认约束
gender char(1) check(gender='男' or gender='女')#检查
age int unique,#唯一
majorID int references major(id)#外键
#查看book表中所有的索引,包括主键、外键、唯一
show index from book;
2、添加表级约束
语法:在各个字段的最下面
constraint 约束名 约束类型(字段名)
drop table if exists book;
create table stuinfo(
id int,
stuname varchar(20),
gender char(1),
seat int,
age int,
majorid int,
constraint pk primary key(id);
- 通用的写法
create table if not exists stuinfo(
id int primary key,
stuname varchar(20) not null,
sex char(1),
age int default 18,
seat int unique,
majorid int,
constraint fk_stuinfo_major foreign key(majorid) references major(id)
);
外键特点:1、要求在从表设置外键关系;2、从表额外键列的
- 修改表时添加约束
- 标识列
又称为自增长列, 可以不用手动的插入值,系统提供默认的序列值。
一、创建表时设置标识列
create table tab_identify(
id int primary key auto_increment,
name varchar(20)
);
五、TCL(transaction control language)事务控制语言
- 事务:一个或一组sql语句组成一个执行单元,这个执行单元要么全部执行,要么全部不执行。
- 事务的ACID属性:
1、原子性:原子性是指事务是一个不可分割的工作单元,事务中的操作要么都发生,要不都不发生;
2、一致性:事务必须使数据库从一个一致性状态变换到另一个一致性状态;
3、隔离性:事务的隔离性是指一个事务的执行不能被其它事务所干扰,即一个事务内部的操作及使用的数据对并发的其它 事务是隔离的,并发执行的各个事务之间不能互相干扰;
4、持久性:持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其它操作和数据库故障不应该对其有任何影响。 - 事务的创建
1、隐式事务:事务没有明显的开启和结束的标记
比如insert 、update、delete语句
2、显式事务:事务具有明显的开启和结束的标志;
前提:必须先设置自动提交功能禁用。
#步骤1
set autocommit=0;
#步骤2:编写事务中的sql语句(select,insert,update,delete)
语句1
语句2
#步骤3:结束事务
commit;提交事务
rollback;回滚事务
演示事务的使用步骤:
#开启事务
set autocommit=0;
start transaction;
#编写一组事务的语句
update account set balance = 500 where username='张无忌';
update account set balance = 1500 where username='赵敏';
#结束事务
commit;
阿灿呀
发布了1 篇原创文章 · 获赞 0 · 访问量 20
私信
关注
内容总结
以上是互联网集市为您收集整理的Mysql基础全部内容,希望文章能够帮你解决Mysql基础所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。