MySQL2

MySQL1-常用配置和常用指令
MySQL2-DQL和DML
MySQL3-DDL和TCL
MySQL4-查询练习

SQL数据类型

数值型:
    整型:
        tinyint         1字节   -128~127/0~255
        smallint        2字符
        mediumint       3字符
        int、integer    4字符-2,147,483,648~2,147,483,647/0~4,294,967,295
        bigint          8字符
    小数:  
        D,M可以省略
        定点数  
            dec、decimal(M,D)   有效范围用M,D定义
        浮点数  
            float(M,D)       4字节
            double(M,D)      8字节
字符型:
    较短的文本:
        char(M)     M可省略,固定长度,耗费空间,效率高
        varcher(M)  M不可省略,可变长度,节省空间,效率低
        binary、varbinary   二进制
        enum('要插入的值1','要插入的值2','要插入的值3') 枚举
        set('要插入的值1','要插入的值2','要插入的值3')  集合
    较长的文本:
        text
        blob(较长的二进制数据)
日期型:
    data        只有日期没有时间
    datatime    有日期和时间不带时区    8字节   持续到9999年
    timestamp   有日期和时间带有时区    4字节   持续到2038年
    time        只有时间没有日期
    year        只有年

数据设计规范

  1. 所有表都使用innodeDB的索引
  2. 字符集统一使用utf-8,如果储存emoj表情,则使用utfbmb4字符
  3. 所有表和字段都加有注释
  4. 单张表数据控制在500w以下
  5. 不使用分区表,不利于扩展和维护
  6. 冷热数据进行分离,减小表的宽度
  7. mysql每个表最多存储4096列,每行85535个字节
  8. 减少I/O磁盘操作,使用redis缓存
  9. 经常使用的列放同一个表中
  10. 不储存图片和文件

索引设计规范

  1. 每个表的索引不超过5个,索引在查询很有利,但是在删除和插入的时候会增加负担
  2. 不能给每一列都添加索引
  3. 每个innoDB都有主键,不使用更新频繁的列做索引
  4. 对于频发查询的使用覆盖索引,避免二次查询,把随机IO改为顺序IO
  5. 哈希索引,适用于全键的等值查询
  6. 位图索引,适合改变较少的,且取值范围较小的,可以大幅度增加效率,更新的可能锁表
  7. 函数索引,以f(x)作为索引,适合用于不区分大小写的查询,同时具有选择的唯一性
  8. 索引带来的问题,日期函数

DQL学习

DQL(Data QueryLanguage)数据查询语言

单行函数

select 函数名(实参列表) [from 表];

字符函数

length() 获取字符集的字节

select length('jojo');

ifnull()判断是否为空

select ifnull(commission_pct,0) as 奖金率 from commission_pct

concat() 拼接字符

select  concat(last_name,first_name) as 姓名 from smployees;

upper()/lower() 变大写/变小写

select upper('jojo'); select lower('JOJO');

substr() 截取字符

索引从1开始

select substr('jojo的奇妙冒险之旅',8) out_put; 
select substr('jojo的奇妙冒险之旅',1,4) out_put;

instr() 返回子串第一次出现的位置

没有为0.

select instr('jojo的奇妙冒险','奇妙') out_put;

trim() 去除指定值

不赋值为空格

select trim('aa' from 'aaaaajoaajoaaaaa') out_put;

lpad()/rpad() 用指定字符左/右填充指定长度.

select lpad('jojo',10,'*') out_put; 
select rpad('jojo',10,'*') out_put;

replace() 替换

select replace('奇妙jojo的奇妙冒险奇妙','奇妙','怪怪') out_put

数学函数

round() 四舍五入

select round(-1.1415926,4);

ceil()/floor() 向上/下取整

select ceil(1.01); select floor(-9.9);

truncate() 阶段

select truncate(1.69999,1);

mod() 去余

select mod(10,3);

日期函数

now() 返回当前系统日期

select now();

curdata() 返回当前系统日期,不包含时间

select curdata();

curtime() 返回当前时间,不包含日期

select curtime();

获取指定部分

年year()
月month()/monthname()
日day()
时hour()
分minute()
秒second()

select year(now());

image

str_to_date() 将字符通过指定格式转换成日期

select str_to_date('1999-3-2','%Y-%c-%d') out_put;

date_format() 将日期转换成字符

select date_format(now(),'%y年%m月%d日') out_put;

其他函数

-- 查看数据库当前使用的版本
select version();

-- 查看当前所在的位置
select database();

-- 查看当前使用者
select user();

流程控制函数

if函数:if else 的效果

select if(10>5, '对','错');

case函数:多项选择

select salary 原始工资,department_id,
case department_id
when 30 then salary*1.1
when 40 then salary*1.2
when 50 then salary*1.3
else salary
end as 新工资
from employees;

case函数:多重if

select salary 原始工资,
case 
when salary>20000 then'A'
when salary>15000 then'B'
when salary>10000 then'C'
else 'D'
end as 工资级别

分组函数

  1. sum(),avg()只支持数值类型的参数格式,
  2. sum(),avg(),max(),min(),count()全忽略null
  3. sum(),avg(),max(),min(),count()都可以和distinct[去重]搭配。
  4. count(*),count(1)统计所有行数,两者效率差不多。
  5. 和分组查询的字段有要求,分组函数一般是group by后的字段使用

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;

SQL92标准

等值连接

  1. 第一张表去匹配第二张表的内容,并对指定内容进行对比筛选。
  2. 多表等值连接的结果为多表的交集部分
  3. n表连接,至少需要n-1个连接条件句
  4. 多表的顺序没有要求
  5. 可以搭配前面的子句进行使用
-- 基本(两个表顺序可调换)
select e.last_name,e.job_id,j.job_title 
from employees e,job j 
where e.`job_id`=j.`job_id`;

-- 添加筛选
select last_name,department_name,commission_pct 
from employees e,departments d 
where e.`department_id`=d.`department_id` 
and e.`commission_pct` is not null;

-- 添加分组
select count(*) 个数,city 
from departments d,locations l 
where d.`location_id`=l.`location_id` 
group by city;

-- 添加排序
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,departments d,locations l 
where e.`department_id`=d.`department_id` 
and d.`department_id`=l.`location_id`;

非等值连接

select salary,grade_level from employees e,job_grades g 
where e.salary between g.lowest_sal and g.highest_sal;

自连接

select e.employee_id,e.last_name,m.employee_id,m.last_name from employees e,employees m
where e.`manager_id` = m.`smployee_id`;

SQL99标准

内连接

等值连接

select last_name,department_ment from departments d
inner join employees e on e.`department_id` = d.`department_id`
where e.'last_name' like "%e%";

非等值连接

select salary,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 e.last_name,m.last_name from employees e
join employees m on e.`manager_id`=m.`employee_id`
where e.`last_name` like '%k%';

外连接

一般用于查询一个表中有,一个表中没有的记录

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

如果从表中有和它匹配的,则显示匹配的值

如果从表中没有和它匹配的,则显示null

外连接查询结果=内连接+主表中有从表中没有的记录

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

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

左外右外交换顺序可以实现同样的效果

全外连接,内连接的结果+表1中有但表2中没有的+表2中有但表1中没有的

左外连接

select b.name,bo.* from beauty b
left outer join boys bo on b.`boyfroend_id` = bo.`id`
where bo.`id` is null;

右外连接

select b.name,bo.* from boys bo
right outer join beauty b on b.`boyfroend_id` = bo.`id`
where bo.`id` is null;

全外连接

select b.* bo.* from beauty b
full outer join boys bo on b.`boyfriend_id` = bo.`id`;

交叉连接,笛卡尔乘积

select b.* bo.* from beauty bcross 
join boys bo;

分组查询

  1. 分组筛选查询,分组前筛选和分组后筛选,

    1. 前后的筛选源不同,前筛选的是原表中的数据,后筛选的是分组表中的结果。
    2. 前后筛选语句位置不同,前筛选放在group by语句前,后筛选放在group by语句后
    3. 前后筛选关键字不同,前筛选使用where,后筛选使用having
  2. order by 支持单个字段分组,多字段分组(用','隔开即可),表达式或函数分组(用的少)

  3. 分组后也可以添加排序,排序放在查询的最后

select 分组函数,列 from 表 [where 筛选条件] group by 分组列表 [order by 字句]

group by


-- 简单查询
select max(salary),job_id 
from employees 
group by job_id;

-- 分组前筛选查询
select avg(salary),department_id 
from employees
where email like "%a%" 
group by department_id;

-- 分组后筛选查询
select count(*),department_id 
from employees 
group by department_id 
having count(*)>2;

-- 按照表达式或函数分组筛选查询
select count(*),length(last_name) len_name 
from employees 
group by length(last_name) 
having count(*)>5;

-- 按多个字段分组
-- 字段顺序可更换,结果不变
select avg(salary),department_id,job_id 
from employees 
group by job_id,department_id;

-- 分组查询,添加排序
select avg(salary),department_id,job_id 
from employees 
where department_id is not null 
group by job_id,department_id 
having avg(salary)>10000 
order by avg(salary) desc;

连接查询

笛卡尔乘积现象

beauty表有12条数据,boys表有4条数据,最终输出出来48行数据

select `name`,boyName from beauty,boys;
-- 解决
select `name`,boyName from boys,beauty 
where beauty.boyfriend_id=boys.id;

子查询

出现在其他语句当中的select语句称为子查询,外部的查询语句称为主查询

子查询放在小括号内,一般子查询的条件语句放在右侧,标量子查询一般搭配单行操作符使用,列子查询一般搭配多行操作符使用

子查询出现的位置:select后(标量子查询),from后(表子查询),where或having后(都支持),exists后(表子查询)

子查询结果行列数不同:标量子查询(一行一列),列子查询(多行一列),行子查询(一行多列),表子查询(多行多列)

标量子查询

-- where后
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 = 142
);

-- having后
select min(salary),department_id
from employees
group by department_id
having min(salary)>(
    select min(salary)
    from employees
    where department_id = 50
);

列子查询

select last_name from employees
where department_id in(
    select distinct department_id
    from departments
    where location_id in (1400,1700)
);

行子查询

-- where后
select *
from employees
where (employee_id,salary) = (
    select min(employee_id),max(salary)
    from employees
);

-- select
select d.*,(
    select count(*)
    from employees e
    where e.`department_id` = d.`department_id`
) 个数 from departments d;

表子查询

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 lowset _sal and highest_sal;

相关子查询

exists(完整的查询语句)结果为1或0,有值为1没值为0

select exists(select employee_id from employees);

select department_name from departments d 
where exists( select * from employees e
    where d.`department_id` = e.`department_id`);

分页查询

一页显示不全,需要分页进行sql请求

limit offset(起始索引,从0开始),size(显示条目数);

select * from employees 
where commission_pct is not null order by salary desc
limit (page-1)*size,size;

联合查询

union 将多条查询语句的结果合并成一个结果,应用于查询的结果来源于多个表,且表之间没有关联

使用多个union可以连接多个句子

select  * from employees 
where email like '%a%' union all select * from employees 
where department_id > 90;

DML学习

DML(Data Manipulation Language)即数据操纵语句,用来查询、添加、更新、删除等

插入语句

插入语句内容需要对应列,省略列名默认安表列进行对应

第一种方法可以一次插入多行,支持子查询

insert into beauty(id,name,sex,borndate,phone,photo,boyfriend_id) 
value(13,'jojo1','男','1881-4-23','18988888',null,2),
(14,'jojo2','男','1881-4-23','18988888',null,2),
(15,'jojo3','男','1881-4-23','18988888',null,2);

-- 简写
insert into  beauty 
set id=19,name='乔纳森·乔斯达',phone='999';

-- 子查询插入
insert into beauty (id,name,phone)
select id,boyname,'123456789'
from boys where id<3;

修改语句

修改单表语句

-- 将name以唐开头的phone字段修改为18888888
update beauty  set `phone`='18888888' 
where name like '唐%';

修改多表语句

92语法

updata 表1 别名,表2 别名
set 列=值,...
where 连接条件
and 筛选条件;

99语法

updata 表1 别名
inner|left|right join 表2 别名
on 连接条件
set 列=值,...
where 筛选条件;

update boys bo 
inner join beauty 
on bo.`id`=b.`boyfriend_id`
set b.`phone`='114'
where bo.`boyname`=`张无忌`

删除语句

单表删除

-- 删除表内id为1的一行数据
-- 可以回滚
delete from stuinfo where id=1;

-- 清空表,不能筛选,效率高,自增长从新开始,不可以回滚
truncate table stuinfo;

多表删除

92语法

delete 表1的别名,表2的别名
from 表1 别名,表2 别名
where 连接条件
and 筛选条件;

99语法

delete 表1的别名,表2的别名
from 表1 别名
inner|left|right join 表2 别名 
on 连接条件
where 筛选条件;

delete b,bo from beauty b
inner join boys bo on b.`boyfriend_id`=bo.`id`
where bo.`boyname`=`黄晓明`;
posted @ 2025-04-01 13:30  *--_-  阅读(40)  评论(0)    收藏  举报