“尚硅谷”Mysql数据库DQL

DB,DBMS,SQL的概念

DB:数据库(database):存储数据的”仓库“。(并非是数仓)。
DBMS:数据库管理系统(Database Management System)。数据库是通过DBMS创建和操作的容器。例如mysql,oracle。
SQL:结构话查询语言(Structure Query Language):专门用来与数据库通信的语言。

DQL数据查询语言

基本查询

“+” 的使用

在mysql中,"+“并不能对字段值进行拼接操作,”+"只能作为运算符来使用。
mysql字符拼接使用拼接函数concat
mysql数据库中字符串和字符并无区别

select查询

select查询的结果可当作一张虚拟的表。

#两个操作数都为数值型,做加法运算。
select 100+90;#190

#其中一方为字符型,试图将字符型数值转换成数值型。
#转换成功,继续做加法运算。
#转换失败,将字符型数值转换为0.
select '100'+90;#190
select 'jack'+90;#90

#其中一方为null,结果为null
select null+20;#null

查询函数

#查询mysql的版本号
select version();

ifnull

select ifnull(sal,0);
#如果sal的值为null,那么就将null替换为0

运算符 <>:不等于

模糊查询

like

通配符:" % " 任意多个字符," _ "任意单个字符 。
当字符发生冲突,可以使用转意字符 " \ " 也可以使用ESCAPE函数。

select name from emp where name like '_$_%' escape '$';
#其中$就被定义为转意字符
select 
		*
from
		emp
where
		name like '__a%'#查询第三个字符为a的员工姓名

between and

包含临界值,等价于: >= and <=,
并且临界值不能够调换顺序。

in

判断某字段的值是否属于in列表中的某一项

select name from emp where name in('jack','tom');

is null

" = "或 " <> "不能用于判断null值。
is null或is not null 可以判断null值,且只能判断null。

安全等于" <=> "也可以判断null值,也可以判断常规数值

排序查询

order by

1.asc:升序 desc:降序。
2.order by 子句中可支持单个字段,多个字段,表达式,函数,别名。
3.order by 子句一般是放在查询语句的最后面,limit子句除外。

select * from emp order by sal desc;#倒叙排序,默认是升序
#按照姓名的长度显示员工姓名和工资【按函数排序】
select length(name) lengths,name,sal from emp order by length(name) desc;
#查询员工信息,要求先按工资排序,再按员工编号排序【按多个字段排序】
select * from emp order by sal,eid desc;

常见函数

一、单行函数

字符函数
#length:获取参数的字节数
select length('john');

# concat:拼接字符
select concat(last_name,'_' first_name) name from emp;

#upper\lower:转换大小写 
select upper('john');
select lower('HHADdsad');

#substr\subString 字符截取
#sql索引从1开始
select substr('huangfeihong',6);#eihong
select substr('shisanyi',1,3);#shi, 3指字符长度

#instr:返回子串第一次出现的索引,如果找不到返回0
select instr('klsdgiwenlafiwenwenwen','wen');#7

#trim:除去前后空格
select trim('   lsls      '); #lsls
#去除前后指定字符
select trim('a' from 'aaaaalsaaalsaaaa');#lsaaals

#lpad:用指定的字符实现左填充到指定长度
select lpad('aaa',5,'*');#aaa**
#如果指定长度大于原本字符长度,则截断原本字符
select lpad('aaa',2,'*');#aa
#rpad:用指定的字符实现右填充到指定长度
select rpad('aaa',5,'x');#xxaaa

#replace: 替换
select replace ('wwaaddt','w','a');#aaaaddt
数学函数
#round:四舍五入
select round(1.45);#1
select round(4.567,2);#4.57,保留两位小数

#ceil:向上取整,返回>=该参数的最小整数
select ceil(1.002);#2
select ceil(-1.002);#-1
#floor:向下取整,返回<=该参数的最大整数
select floor(-9.99);

# truncate:截断
select truncate(1.69999,1);#1.6

# mod:取余
select mod(10,3);#1

日期函数
#now 返回当前系统日期+时间
select now();#2020-09-03 45:56:11

#curdate 返回当前系统日期,不包含时间
select curdate();#2020-09-03

#curtime 返回当前时间,不包含日期
select curtime();#45:56:11

#获取指定的部分,年月日时分秒
select year(now());#2020
select year('1998-4-4');#1998
select month(now());#9
select monthname(now());#September

#str_to_date 将字符通过指定的格式转换成日期
select str_to_date('1998-3-2','%Y-%c-%d');#1998-03-02 
select str_to_date('4-3 1992','%c-%d %Y');#1992-4-3 00:00:00

#date_format 将日期转换成字符
select date_format(now(),'%yn年%m月%d日');#20年09月03日

在这里插入图片描述

流程控制函数
#if :if else效果
select if(10<5,'da',"xiao");#xiao
#case: switch case 效果
/*
case 要判断的字段或表达式
when 常量1 then 要显示的值1或语句1;
when 常量2 then 要显示的值2或语句2;
else 要显示的值n或语句n;
end
*/
#查询工资,部门编号为20,30,40分别为工资的1.1倍,1.2倍,1.3倍
select sal,deptno,
case deptno
when 30 then sal*1.1
when 40 then sal*1.2
when 50 then sal*1.3
else sal
end
from emp;
# case : 类似于多重if
/*case
when 条件1 then 显示的值1或语句1
when 条件2 then 显示的值2或语句2
else 显示的值n或者语句n
end
*/
/*
如果工资>20000 A级
工资>15000 B级
工资>10000 c级
否则,d级
*/
select sal,
case
when sal>20000 then 'a'
when sal>15000 then 'b'
when sal>10000 then 'c'
else 'd'
end
from emp;

其他
select version();#mysql版本号
select database();#当前数据库
select user();#当前的用户

二、分组函数

功能:用作统计使用,又称为聚合函数或统计函数或组函数。
sum,avg,max,min,count

**特点:
1、sum、avg一般用于处理数值型,max、min、count可以处理任何类型。
2、以上分组函数都忽略null值。
3、可以和distinct搭配使用。
4、和分组函数一同查询的字段有限制,一同查询的字段要求是group by后的字段。
例:select avg(sal),name from emp;两个字段不能同时使用,avg的返回字段为一个,对应name为多个,无法进行匹配,语句虽不会报错,但是没有意义。
**

count(*):查询表的总行数
count(1):相当于在表中加入了一列1,统计1的个数,也就是表的总行数。

效率: 
MYISAM存储引擎下,count(*)的效率高。
INNODB存储引擎下,count(*)和count(1)效率差不多,比count(字段)高一些。

分组查询

group by 大都与分组函数进行连用。
可以使用having 对条件进行补充。

至于是否使用having,还是使用where,要根据条件是在分组之前进行还是在分组之后进行的。

select deptno,avg(sal) avg_sal from emp group by deptno having avg_sal > 2000 order by deptno desc;

连接查询

一、sql92标准:只支持内链接

1、等值连接

1、多表等值连接的结果为多表的交集部分
2、n表连接,至少需要n-1个连接条件
3、多表的顺序没有要求
4、一般需要为表起别名

select name,deptname,city
from emp e,dept d,locations l
where e.deptno=d.deptno and d.loc = l.loc;

2、非等值连接

select sal,grade_level
from emp e,job g
where sal between g.low_sal and g.high_sal; 

3、自连接

select empno,name,empno,name
from emp e,emp m
where e.manager_id=m.empno;

sql99语法

内连接:[inner] join on

等值连接

select name,dname from emp e inner join dept d on e.deptno=d.deptno where name like '%e%';
select d.dname,count(*) count_1 from emp e 
inner join dept d on e.deptno=d.dpetno 
group by dname having count_1>3 
order by count_1 desc;

非等值连接
grade_level :工资级别

select count(*),grade_level
from emp e
join job_grades g 
on e.sal between 1000 and 5000
group by grade_level
having count(*) >20
order by grade_level desc;

自连接

select e.name,m.name
from emp e 
join emp m 
on e.manager_id = m.empno;
外连接

左外 : left [outer] join on
右外 : right [outer] join on
全外 : full [outer] join on
特点:

外连接的查询结果为主表中的所有记录
			如果从表中有和它匹配的,则显示匹配的值
			如果从表中没有和它匹配的,则显示null
			外连接查询结果=内连接结果+主表中有而从表没有的记录
全外连接:显示表中所有记录,不匹配的使用null值代替,mysql不支持
交叉连接 :cross join on

就是一个笛卡尔积

select e.*,d.*
from emp e
cross join dept d;

子查询

含义:出现在其他语句中的select语句,称为子查询或内查                			询,外部的查询语句,称为主查询或外查询。
分类:
       select后:仅仅支持标量子查询
       from后:支持表子查询
       where或having后:标量子查询,列子查询,行子查询
       exists后:表子查询
按结果集的行列数不同:
				标量子查询(结果集只有一行一列)
				列子查询(结果集只有一列多行)
				行子查询(结果集有一行多列)
				表子查询(结果集一般为多行多列)

一、where或having后面

1、标量子查询(单行子查询)
2、列子查询(多行子查询)
3、行子查询(多列多行)

特点:
①子查询放在小括号内
②子查询一般放在条件的右侧
③标量子查询,一般搭配着单行操作符使用 > < >= <= = <>

列子查询,一般搭配多行操作符使用 in、any/some、all

标量子查询(单行子查询)

#查询公司工资最少的员工
select last_name,job_id,salary
from emp e
where salary=(
		select min(salary)
		from emp
);
#查询最低工资大于50号部门的最低工资的部门id和其最低工资
select min(sal) from emp where deptno=50; t1
select deptno,min(sal) min_sal from emp group by deptno having min_sal>t1;

列子查询

#查询location_id是1400或1700的部门号
select name 
from emp
where deptno in (
		select distinct deptno
		from dept
		where location_id in(1400,1700)
)
#返回其他工种中比job——id为'IT_PROG'工种任一工资低的员工号、姓名、job_id、sal
select distinct sal from emp where job_id = 'IT_RPOG'; t1
select empno,ename,job_id,sal from emp where sal<any(t1) 
and job_id <> 'IT_PROG';

行子查询

#查询员工编号最小并且工资最高的员工信息
select * from emp
where (empno.sal) = (
	select min(empno),max(sal)
	from emp
);

二、select后面

#查询每个部门的员工个数
select d.*,
(select count(*) from emp e
where e.deptno = d.deptno)
from deptno d;

三、from后面

必须起别名

#查询每个部门的平均工资等级
select ag_dep.*,g.grade_level
from (
select avg(sal) ag,deptno
from emp 
group by deptno) ad_dep
join job_grades g 
on ag_dep.ag between lowest_sal and highest_sal;

四、exists后(相关子查询)

exists表示是否存在
1或0
先执行主查询再执行子查询

select exists(select empno from emp);#1
select dname from dept d 
where exists(
	select * from emp e
	where d.deptno=e.deptno);

分页查询

应用场景:当要显示的数据,一页显示不全,需要分页提交sql请求。
limit 【offset】,size
offset:要显示条目的起始索引(起始索引从0开始)
size:要显示的条目个数

#查询11条-25条数据
select * from emp limit 10,15;

union联合查询

union:将多条查询语句的结果合并成一个结果。
特点
1、要求多条查询语句的查询列数是一致的。
2、要求多条查询语句的查询的每一列的类型和顺序最好一致。
3、union默认是去重的,使用union all可包含重复字段

#查询部门编号>90或邮箱包含a的员工信息
select * from emp where email like '%a%'
union
select * from emp where deptno>90;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值