美文网首页
MySQL学习(一)

MySQL学习(一)

作者: kevin5979 | 来源:发表于2020-11-02 19:27 被阅读0次

*笔记是在https://www.bilibili.com/video/av49181542学习时记录

安装MySQL

相关概念

DB:

数据库(database):存储数据的“仓库”,它保存了一系列有组织的数据

DBMS:

数据库管理系统(Database Management System),数据库是通过DBNS创建和操作的容器

SQL:

结构化查询语言(Structure Query Language),专门用来与数据库通信的语言
特点:
1、不是某个特定数据库供应商专有的语言,几乎所有的DBMS都支持SQL
2、简单易学
3、虽然简单,但实际上是一种强有力的语言,灵活使用其语言元素,可以进行非常复杂和高级的数据库操作


MySql操作

  1. 进入数据库:mysql -hlocalhost -uroot -p
  2. 查看当前所有的数据库:show databases;
  3. 打开指定的库:use 库名;
  4. 查看当前库的所有表:show tables;
  5. 查看其它库的所有表:show tables from 库名;
  6. 创建表:
create table 表名(
  列名 列类型,
    列名 列类型,
    ...
);
  1. 查看表结构:desc 表名;
  2. 查看服务器的版本:
方式一: 登录到mysql服务端, select version();
方式二: 没有登录到mysql服务端, mysql --version 或者 mysql -V

MySQL的语法规范

  1. 不区分大小写,但建议关键字大写,表名、列名小写
  2. 每条命令最好用分号结尾
  3. 每条命令根据需要,可以进行缩进或换行
  4. 注释:
#单行注释
-- 单行注释
/* 多行注释 */

DQL语言的学习(数据库查询语言)

基础查询

语法:select 查询列表 from 列名

  • 查询列表可以是:表中的字段、常量值、表达式、函数
  • 查询的结果是一个虚拟的表格
# 1.查询表中的单个字段
select name from employees;

# 2.查询表中的多个字段
select name,id from employees;

# 3.查询表中的所有字段
select * from employees;

# 4.查询常量值
select 100;

# 5.查询表达式
select 100 % 98;

# 6.查询函数
select version();

# 7.起别名
select 100%98 as 结果;
select last_name as 姓,first_name as 名 from employees;
select last_name 姓,first_name 名 from employees;
select name as "姓 名" from employees;

# 8.去重
# 查看员工表中涉及到的所有部门编号
select disTinct de_id from employees;

# 9.+号的作用
select '13' + 90 -> 103
select 'join' + 20 -> 20
select null + any -> NULL

# 10.concat拼接
# 将员工姓和名字段连接成 姓名
select concat(last_name,first_name) as 姓名 from employees;

# 11.IFNULL(判断字段,替换值)
select IFNULL(num,0) as 数字 from employees;

条件查询

语法:select 查询列表 from 表名 where 筛选条件;

分类:

一、按条件表达式筛选

条件运算符:> < = != <> >= <=

二、按逻辑表达式筛选

逻辑运算符:&& || ! and or not

三、模糊查询

like between and in is null

-- 按条件表达式筛选-----------------------------------

# 1.查询工资大于 12000 的员工信息
select * from employees where salary > 12000;

# 2.查询部门编号不等于90号的员工名和部门编号
select name,id from employees where department_id <> 90;

-- 按逻辑表达式筛选-----------------------------------

# 1.查询工资在10000到20000之间的员工名、工资以及奖金
select name,salary,com from employees where salary >= 10000 and salary <= 20000;

-- 模糊查询------------------------------------------
/* 
    一般和通配符搭配使用
    % 任意多个字符,包含0个字符
    _ 任意单个字符
*/
# 1.like
# 查询员名中包含字符a的员工信息
select * from employees where name like '%a%';

# 查询员工名中第三个字符为e,第五个字符为a的员工名和工资
select name,com from employees where name like '__e_a%';

# 查询员工名中第二个字符为_的员工名
select name from employees where name like '_\_%';
select name from employees where name like '_$_%' escape '$';


# 2.between and (包含临界值, 临界值不能颠倒顺序)
# 查询员工编号在100到200之间的员工信息
select * from employees where id between 100 and 200;


# 3.in
# 查询员工的工种编号是it_prog、ad_VP、ad_pres中的一个员工名和工种编号
select name,id from employees where job_id in ('it_prog','ad_VP','ad_pres');

# 4.is null (不能判断 = 或 != )
# 查询没有奖金的员工名和奖金率
select name,com from employees where comm_pct IS NULL;
select name,com from employees where comm_pct IS NOT NULL;

# 5.安全等于 <=> (既可以判断 =, 也可以判断 NULL)
# 查询没有奖金的员工名和奖金率
select name,com from employees where comm_pct <=> NULL;

排序查询

语法:select 查询列表 from 列名 [where 筛选条件] order by 排序列表(asc | desc)

  1. asc(默认):表示升序,不写默认
  2. desc :降序
  3. order by 字句可以支持单个字段、多个字段、表达式、函数、别名
  4. order by 字句一般是放在查询语句的最后面 (limit字句除外)
# 1.查询员工信息,要求工资从高到低排序
select * from employees order by salary desc; 
select * from employees order by salary asc; 

# 2.查询部门编号 >= 90 的员工信息,按入职时间先后进行排序
select * from employees where id >= 90 order by hiredata asc;

# 3.按年薪的高低显示员工的信息和年薪 【按表达式排序】
select *,salary*12*(1+ifnull(commission_pct,0)) as 年薪 
from employees
order by salary*12*(1+ifnull(commission_pac)) desc;

# 4.按年薪的高低显示员工的信息和年薪 【按别名排序】
select *,salary*12*(1+ifnull(commission_pct,0)) as 年薪 
from employees
order by 年薪 desc;

# 5.按姓名的长度显示员工的姓名和工资 【按函数排序】
select length(name) as 字节长度,name,salary from employees order by length(name) desc;

# 6.查询员工信息,要求先按工资升序排序,再按员工编号降序排序 【按多个字段排序】
select * from employees order by salary asc,id desc;


常见函数

语法:select 函数名(实参列表) 【from 表】;

分类:

  1. 单行函数:concat、length、ifnull 等
  2. 分组函数:做统计使用,又称为统计函数、聚合函数、组函数

单行函数

一、字符函数
# 1.length  获取参数值得字节个数
select length('john');                  # 4
select length('张三丰hahaha');           # 15

# 2.concat  拼接字符串
select concat(name."_",id) as 姓名 from employees;

# 3.upper、lower  大小写
select upper('john');   # JOHN
select lower('JOHn');   # john
# 将姓变大写、名变小写,然后拼接
select concat(upper(first_name),lower(last_name)) as 姓名 from employees;

# 4.substr、substring    截取字符串
# 注意: 索引从 1 开始
select substr('abcdefg',5) as out_put;          # efg
select substr('abcdefg',1,3) as out_put;        # abc 全闭 [1,3]
# 姓名中首字符大写,其他字符小写然后用_拼接,显示出来
select concat(upper(substr(first_name,1,1)),'_',lower(substr(last_name,2))) 
as name from employees;

# 5.instr   返回子串第一次出现的起始索引  没找到返回 0
select instr('abcdefg','ef') as out_put;        # 5

# 6.trim    去掉前后两边的空格
select length(trim('   abc   ')) as out_put    # 3
select length(trim('1' from '11111abc11abc11111')) as out_put    # 8

# 7.lpad    用指定的字符实现左填充
select lpad("abc",8,"1") as out_put;    # 11111abc
select lpad("abc",2,"1") as out_put;    # bc

# 8.rpad    用指定的字符实现右填充
select lpad("abc",8,"1") as out_put;    # abc11111

# 9.replace     替换/多个替换
select replace('abcde','abc','123') as out_put;     # 123de

二、数学函数
# 1.round       四舍五入 (绝对值四舍五入,再添加符号)
select round(1.6);          # 2
select round(-1.6);         # -2
select round(1.6789,2);     # 1.68

# 2.ceil        向上取整,返回 >= 该参数的最小整数
select cell(1.2);       # 2
select cell(-1.2);      # -1

# 3.floor       向下取整,返回 <= 改参数的最大整数
select floor(9.2);      # 9
select floor(-9.2);     # -10

# 4.truncate    截断
select truncate(1.666,2);       # 1.67

# 5.mod     取余(结果符号取决于被除数) mod(a,b) => a-a/b*b
select mod(5,3);        # 2 ( 5%3 )
select mod(-5,3);       # -2 ( -5%3 )

# 6.rand    获取随机数,[0,1)之间的小数
select rand()
三、日期函数
# 1.curdate     返回当前系统日期
select curdate();

# 2.curtime     返回当前时间
select curtime();

# 3.now()       返回当前系统日期 + 时间
select now();       # 2019-10-3 12:02:35

# 4.获取 年月日、时分秒等     year month day hour minute second
select year(now()) as 年;            # 2019
select year('1999-10-10') as 年;     # 1999

# 5.str_to_data     将日期格式的字符串转换成指定格式的日期
select str_to_data('1999-9-10','%y-%c-%d') as out_put        # 1999-09-10
select * from test where date = '1999-12-12'

# 6.date_format     将日期转换成字符
data_format('2019/10/3','%Y年%m月%d日')        # 2019年10月3日

# 7.datediff        返回两个日期相差的天数

四、流程控制函数
# 1.if      if else 效果(表达式 ? : )
select if(2>3,'对','错')

# 2.case

/*
    switch case 效果:
    case 要判断的表达式
    when 常量1 then 要显示的值或语句;
    when 常量2 then 要显示的值或语句;
    ...
    else 要显示的值或语句
    end
*/
# 要求: 查询员工工资,按入职时间 显示2016为1.5, 2017为1.3, 2018为1.1,其余为原工资
select salary as 原来工资,add_date,
case year(add_date)
when '2016' then salary * 1.5
when '2017' then salary * 1.3
when '2018' then salary * 1.1
else salary * 1
end as 新工资 from employees;

/*
    多重if效果:
    case
    when 条件1 then 要显示的值或语句
    when 条件2 then 要显示的值或语句
    ...
    else 要显示的值或语句
    end
*/
# 要求: 工资 > 20000 显示A, >10000 显示B, >5000 显示C, 其余显示D
select salary,
case
when salary > 20000 then 'A'
when salary > 10000 then 'B'
when salary > 5000 then 'C'
else 'D'
end as 级别 from employees


四、其他函数
# 1.version     当前数据库服务器的版本
# 2.database    当前打开的数据库
# 3.user        当前用户
# 4.md5('字符')  字符md5加密


习题
  1. 显示系统时间(日期 + 时间)
select now();

  1. 查询员工号,姓名,工资,以及工资提高百分之二十之后的结果(new salary)
select id,name,salary,salary*1.2 as "new salary" from employees;

  1. 将员工的姓名按首字母排序,并写出姓名的长度(length)
select length(name) 长度,substr(name,1,1) as 首字符,name from employees order by 首字符;

  1. 做一个查询,产生下面结果
/*
<name> earns <salary> monthly but wants <salary * 3>
Dream Salary
King earns 24000 monthly but wants 72000
*/
select concat(name,'earns',salary,'monthly but wants',salary*3) as "Dream Salary" from employees where salary=24000;


  1. 使用 case-when ,按照下面的条件 :

​ job grade

AD_PRES A

ST_MAN B

IT_PROG C

​ 其他 D

select job,
case jop
when 'AD_PRES' then 'A'
when 'ST_MAN' then 'B'
when 'AD_PROG' then 'C'
else 'D'
end as Grade from employees;

分组函数

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

分类:

sum 求和、avg 平均值,max 最大值、count 计算个数

一、简单的使用
# 1.sum     总和
select sum(salary) from employees;

# 2.avg     平均值
select avg(salary) from employees;
1
# 3.min     最小值
select min(salary) from employees;

# 4.max     最大值
select max(salary) from employees;

# 5.count   计数
select count(salary) from employees;

# 6.合并使用
select sum(salary) as 总和,round(avg(salary),2) as 平均值 from employees;

二、参数支持哪些类型
# 1. sum、avg : 用于处理数值型
#    max、min、count : 可以处理任何类型

# 2. 以上函数都忽略 null 值

# 3. 可以和distinct(去重)搭配 eg: select sum(distinct salary) from employees;

# 4. count 函数的详细介绍
-- 查询有多少行(不全为null)
select count(*) from employees;
select count(1) from employees;    # 在每行加个字段1, 再计算数量
注意: count(*) 比 count(字段) 的效率高 字段要判断是否为null,才 +1

# 5.和分组函数一同查询的字段有限制
eg: select avg(salary),id from employees;


习题
  1. 查询公司员工工资的最大值,最小值,平均值,总和
select max(salary) as 最大值,min(salary) as 最小值,avg(salary) as 平均值,count(salary) as 总和 from employees;

  1. 查询员工表中的最大入职时间和最小入职时间的相差天数
select datediff(max(date),min(date)) as 相差天数 from employees;

  1. 查询部门编号为90的员工个数
select count(*) 个数 from employees where id = 90;

分组查询

语法:

select 分组函数,列(要求出现在group by后面) from 表【where】group by 分组列表 【order by 字句】;

注意:

查询列表必须特殊,要求是分组函数和group by后出现的字段

特点:

1、分组查询中的筛选条件分为两类

数据源 位置 关键字
分组前筛选 数据表 group by字句的前面 where
分组后筛选 分组后的结果集 group by字句的后面 having

1. 分组函数做条件肯定是放在having字句中

2. 能用分组前筛选的,尽量优先考虑使用分组前筛选

一、简单查询
# 1.查询每个工种的最高工资
select max(salary),id from employees group by id;

# 2.查询每个位置上的部门个数
select count(*),location_id from departments group by location_id; 


二、添加筛选条件
# 1.查询邮箱中包含a字符的,每个部门的平均工资
select avg(salary),department_id from employees where email like '%a%' group by department_id;

# 2.查询有奖金的每个领导手下员工的最高工资
select max(salary),manager_id from employees where commission_pct is not null group by manager_id;


三、添加复杂的筛选条件
# 1. 查询哪个部门的员工个数 > 2
① 查询每个部门的员工个数
select count(*),department_id from employees group by department_id;
② 根据①的结果进行筛选,查询哪个部门的员工个数 > 2
select count(*),department_id from employees group by department_id having count(*) > 2;


# 2.查询每个工种有奖金的员工的最高工资 > 12000 的工种编号和最高工资
①查询每个工种有奖金的员工的最高工资
select max(salary),id from employees where commission_pct is not null group by id;
②根据①的结果继续筛选,最高工资 > 12000
select max(salary),id from employees where commission_pct is not null group by id having max(salary) > 12000;


# 3.查询领导编号 > 102 的每个领导手下的最低工资 > 5000 的领导编号是哪个,以及其最低工资
①查询每个领导手下员工的最低工资
select min(salary),manager_id from employees group by manager_id;
②添加筛选条件: 编号 > 102
select min(salary),manager_id from employees where mangager_id > 102 group by manager_id;
③添加筛选条件: 最低工资 > 5000
select min(salary),manager_id from employees where mangager_id > 102 group by manager_id having min(salary) > 5000;


# 4.按员工姓名的长度分组,查询每一组的员工个数,筛选员工个数>5的有哪些
①查询每个长度的员工个数
select count(*),length(name) from employees group by length(name);
②添加筛选条件,筛选员工个数 > 5 的
select count(*) as c,length(name) as n from employees group by n having c > 5;


# 5.查询每个部门每个工种的员工的平均工资
select avg(salary),department_id,job_id from employees group by department_id,jop_id;


# 6.查询每个部门每个工种的员工的平均工资,并且按平均工资的高低显示
select avg(salary),department_id,job_id from employees group by job_id,department_id order by avg(salary) desc;



连接查询

含义:又称多表查询,当查询的字段来自于多个表时,就会用到连接查询

分类:

按年代分类: sql92标准(仅仅支持内连接)、sql99标准(不支持全外连接)【推荐】
按功能分类: 内连接(等值连接,非等值连接,自连接)、外连接(左外连接,右外连接,全外连接)、交叉连接

sql92标准

1、等值连接
# 1.查询商品和对应的分类
select good_name,class_name from goods,classity where goods.id = classify.id;

# 2.查询员工名和对应的部门名
select name,department_name from employees,departments where employees.department_id=departments.department_id;


为表起别名
  1. 提高语句的简洁度
  2. 区分多个重名的字段
  3. 起别名和原表名不能同一个语句中使用
# 1.查询员工名、工种号、工种名
select e.name,e.job_id,j.job_title from employees as e,jobs as j where e.job_id = j.job_id;

# 2.查询有奖金的员工名、部门名
select name,d_name,commission_pct from employees as e,departments as d where e.d_id = d.d_id and e.commission_pct is not null;

# 3.查询每个城市的部门个数
select count(*) 个数,city from department d,locations l where d.location_id = l.location_id group by city;

# 4.查询有奖金的部门的部门名和部门领导编号,和该部门的最低工资
select department_name,d.manager_id,min(salary) from departments as d,employees as e where d.department_id = e.department_id and commission_pct is not null group by department_name,d.manager_id;

# 5.查询每个工种的工种名和员工的个数,并且按员工个数降序
select job_title,count(*) from employees e,jobs j where e.job_id = j.job_id group by job_title order by count(*) desc;


2、非等值连接
# 1.查询员工的工资和工资级别
select salary,grade_level from employees e,job_grades g where salary between g.low_sal and g.high_sal;

3、自连接
# 1.查询员工名和上级的名称
select e.emplotees_id,e.name,m.employees_id,m.name from employees e,employees m where e.manager_id = m.employee_id;

习题
  1. 显示员工表的最大工资,工资平均值
select max(salary),avg(salary) from employees;

  1. 查询员工表的employee_id,job_id,name, 按department_id降序, salary升序
select employee_id,job_id,name from emploees order by department desc,salary asc;

  1. 查询员工表的job_id中包含 a 和 e 的,并且 a 在 e 前面
select job_id from employees where job_id like '%a%e%';

  1. 已知表 student,里面有id(学号),name, gradeId(年级编号)

已知表 grade, 里面有id(年级编号),name(年级名)

已知表 result, 里面有id, score, studentNo(学号)

要求查询姓名、年级名、成绩

select s.name,g.name,score from student as s,grade g,result s where s.gradeId = g.id and s.id = r.studentNo;

  1. 显示当前日期,以及去前后空格,截取子字符串的函数
select now();
select trim(字符 from '');
select substr(str,startIndex);
select substr(str,startIndex,len);

sql99标准

内连接(☆)inner

外连接(左外(left☆)、右外(right☆)、全外full

交叉连接 cross

语法

**select 查询列表 **

from 表1 别名 【连接类型】

**join 表2 别名 **

**on 连接条件 **

**【where 筛选条件】【group by 分组】【having 筛选条件】 【order by 排序列表】; **

一、内连接

select 查询列表 from 表1 别名 inner join 表2 别名 on 连接条件;

# 等值连接
# 1.查询员工名、部门名(调换位置)
select name,department_name 
from employees e 
inner join departments d 
on e.department_id = d.department_id;

# 2.查询名字中包含e的员工名和工种名(筛选)
select name,job_title 
from employees 
inner join jobs j 
on e.job_id = j.job_id 
where name like '%e%';

# 3.查询部门个数>3的城市名和部门个数(分组、筛选)
select city_name,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 departments d
on e.department_id = d.department_id
group by department_name;
②在①结果上筛选员工个数 > 3的记录,并排序
select count(*) 个数,department_name
from employees e
inner join departments d
on e.department_id = d.department_id
group by department_name
having count(*) > 3
order by count(*) desc;

# 5.查询员工名、部门名、工种名,并按部门名降序(三表连接)
select name,department_name,job_title
from employees e
join departments d on e.department_id = d.department_id
join jobs j on e.job_id = j.job_id
order by department_name desc;



# 非等值连接
# 1.查询员工的工资级别
select salary,grade_level 
from employees e 
join job_grades g 
on e.salary between g.lowest_sal and g.highest_sal;

# 2.查询工资级别的个数 > 10的个数,并且按工资级别降序
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;



# 自连接
# 1.查询员工的名字、上级的名字
select e.name,m.name
from employees e
join employees m
on e.manager_id = m.employee_id;

二、外连接

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

外连接的查询结果为主表中的所有记录

  • 如果表中有和它匹配的,则显示匹配的值
  • 如果表中没有和它匹配的,则显示 null
  • 外连接查询结果 = 内连接结果 + 主表中有而从表没有的记录

左外连接:left join左边的是主表

右外连接:right join右边的是主表

# 1.查询没有注册的学生名字
# 左外连接
select s.name 
from students s left outer join logon l 
on s.logon_id = l.logon_id
where l.login_id is null;
# 右外连接
select s.name 
from logon l right outer join students s 
on s.logon_id = l.logon_id
where l.login_id is null;

# 交叉连接 (笛卡尔积)
select s.*,t.*
from student s cross join teacher t;

习题
# 1.查询编号大于3的学生的老师信息,如果有,列出详细信息,没有,用null填充
select s.id,t.*
from student s left outer join teacher t 
on s.t_id = t.t_id
where s.id > 3;

# 2.查询哪个城市没有部门
select city
from departments d
right outer join locations l
on d.location_id = l.location_id
where d.department_id is null;

# 3.查询部门名为SAL或IT的元工信息
select e.*,d.department_name
from departments d left join employees e
on d.department_id = e.department_id
where d.department_name in('SAL','IT');

子查询

概念:出现在其他语句内部的select语句,称为子查询或内查询

分类:

按子查询出现的位置:

  • select 后面:仅仅支持标量子查询
  • from 后面:支持表子查询
  • where 或 having 后面:标量子查询√ 列子查询√ 行子查询
  • exists 后面(相关子查询):表子查询

按结果集的行列数不同:

标量子查询(结果集只有一行一列)

列子查询(结果集有一列多行)

行子查询(结果集有一行多列)

表子查询(结果集有多行多列)

# 1.查询工资比zhangsan高的员(标量子查询)
①查询zhangsan的工资
select salary from employees where name = 'zhangsan';
②查询员工信息 salary > ①的结果
select * from employees where salary > (
    select salary from employees where name = 'zhangsan'
);

# 2.查询成绩为89或90的所有同学姓名
select s_name from student where s_id in(
    select s_id from result where score in (89,90)      # 结果多行一列
);


分页查询

limit offset,size

放在查询语句最后,offset 要显示的起始索引(从0开始),size 条数

# 1.查询前五条员工信息[0,5)
select * from employees limit 0,5;

# 2.查询第 11-25 条
select * from employees limit 10,15;

执行顺序

select 查询列表

from 表

连接类型 join 表2

on 连接条件

where 筛选条件

group by 分组列表

having 分组后的筛选

order by 排序列表

limit 偏移,条目数;

联合查询(默认去重)

将多条查询结果合成一个结果, union all 不去重

语法

查询语句1 union 查询语句2 union ...

# 1.查询中国和外国参赛选手年纪小于20的选手信息
select * from t_c where age < 20
union
select * from t_u where age < 20;

END

相关文章

网友评论

      本文标题:MySQL学习(一)

      本文链接:https://www.haomeiwen.com/subject/eokqektx.html