欢迎光临
我们一直在努力

数据库查询语言DQL全解析

数据库类型分为关系型数据库(比如MySQL)和非关系型数据库(NoSQL)。


数据库管理系统(DBMS):国内常见的有MySQL,Oracle等。


结构化查询语言(SQL,Structured Quary Language):

1.DQL,数据查询语言,select

2.DDL,数据定义语言,修改的是表结构,create,alter,drop

3.DML,数据操纵语言,对表数据进行操作,insert,update,delete

4.DCL,数据控制语言,权限问题,grant,revoke

5.TPL,数据事务管理语言,commit,rollback

6.CCL,指针控制语言


DQL语言简介

DQL(Data Query Language)是SQL的子集,专门用于数据查询操作,核心命令为SELECT。它不修改数据,仅从数据库中检索信息,是数据分析、报表生成的基础工具。


基本语法结构

SELECT column1, column2
FROM table_name
WHERE condition
GROUP BY column
HAVING group_condition
ORDER BY column
LIMIT offset, count;

  • SELECT:指定查询的列(可使用*表示所有列)。select后面既可以跟变量也可以跟常量。

  • FROM:指定数据来源的表。

  • WHERE:过滤行级数据(不可与聚合函数共用)。

  • GROUP BY:按列分组,常与聚合函数(如SUM、COUNT)配合使用。

  • HAVING:过滤分组后的数据(类似WHERE,但用于聚合结果)。

  • ORDER BY:排序(ASC升序,DESC降序)。

  • LIMIT:限制返回行数。

  • DISTINCT:去重。(只能出现在所有字段之前)


数据处理函数

字符串相关

转大写upper和ucase。例如

select upper(ename) as ename from emp;

转小写lower和lcase。同上。


截取字符串substr。语法:substr('被截取的字符串',起始下标,截取长度)。

有两种写法:

    第一种:substr(''被截取的字符串',起始下标,截取长度)

    第二种:substr('被截取的字符串',起始下标)

select substr('abcdef',2,3);

注意:起始下标从1开始,不是从0开始。(1表示从左侧开始的第一个位置,-1表示从右侧开始的第一个位置。)不管是1还是-1都是从左往右截取。

练习:找出员工名字中第二个字母是A的

select ename from emp where substr(ename,2,1)='A';


获取字符串长度length

select length('你好123');

length统计字节长度,输出结果为7(一个汉字两个字节)。

select char_length('你好123');

char_length统计字符个数,输出结果为5。


字符串拼接

语法:concat('字符串1','字符串2')

拼接的字符串数没有限制。


去除字符串前后空白trim

默认是去除前后空白,也可以进行去除指定的前缀后缀。

去除前置0,例如:

select trim(leading '0' from '000111000');

去除后置0,例如:

select trim(trailing '0' from '000111000');

前置0和后置0都去除:

select trim(both '0' from '000111000');


rand()生成0到1的随机浮点数。

rand(x)生成0到1的随机浮点数,通过指定整数x来确定每次获取到相同的浮点值。


round(x)四舍五入,保留整数位,舍去所有小数。

round(x,y)四舍五入,保留y位小数。


truncate(x,y)舍去,例如

select truncate(9.999,2);

输出结果为9.99。以上SQL表示保留两位小数,剩下的全部舍去。


ceil函数:返回大于或等于数值x的最小整数。

floor函数:返回小于或等于数值x的最大整数。


空处理

ifnull(x,y),空处理函数,当x为NULL时,将x当作y处理。

infnull(comm,0),表示如果comm是null时当做0处理。

在SQL语句中,凡是有NULL参与的数学运算,最终的结算结果都是NULL。


now():获取的是执行select语句的时刻。

sysdate():获取的是执行sysdate()函数的时刻。

curdate():获取当前日期。


date_add函数的作用:给指定的日期添加间隔的时间,从而得到一个新的日期。

date_add函数的语法格式:date_add(日期,inter expr单位),例如

select date_add('2023-01-09',interval 3 day);
#输出为2023-01-06

注:日期:一个日期类型的数据

        interval:关键字,翻译为‘间隔’,固定写法。

       expr:指定具体的间隔量,一般为数字。也可以为数字,若为负数,效果和date_sub函数相同。

       单位:year,month,day,hour,minute,second,microsecond,week,quarter

复合型单位:a_b,写法如

select date_add('2022-10-01 10:10:10',interval '3,2' day_hour);
#输出为2022-10-04 12:10:10


date_format日期格式化函数

将日期转换为具有某种格式的日期字符串,通常用在查询操作中。(date类型转换为char类型)

语法格式:date_format(日期,'日期格式')

该函数有两个参数:

·第一个参数:日期。这个参数就是即将要被格式化的日期。类型是date类型。

·第二个参数:指定要格式化的格式子字符串。

  ○%Y:四位年份

  ○%y:两位年份

  ○%m:月份(1…12)

  ○%d:日(1….30)

  ○%H:小时(0…23)

  ○i:分(0…59)

  ○s:秒(0…59)

注意:在mysql中,默认的日期格式就是:%Y-%m-%d %H:%i:%s,所以直接输出日期数据时,会自动转化成该格式的字符串。


str_to_date函数

作用是将char类型的日期字符串转换成日期类型date,通常使用在插入和修改操作当中。(char类型转换成date类型)


dayofweek,dayofmonth,dayofyear函数

示例:

select dayofweek(now());
#一周中的第几天


last_day函数:获取给定日期所在月的最后一天的日期

select last_day(now());


datediff函数:计算两个日期之间所差天数。(时分秒不算,只算天数)

select datediff('1970-02-01 20:10:30','1970-01-01');

timediff函数:计算两个日期所差时间。

select timediff('1970-01-02 20:10:30','1970-01-01 20:09:30');
#输出为24:01:00


if函数

如果条件为TRUE则返回“YES”,如果条件为“FALSE”则返回“NO”:

select if(500<1000,"YES","NO");

再例如:工作岗位是M的工资上调10%,是S的工资上调20%,其他岗位工资照常。(嵌套)

select ename,sall,job,if(job='M',sal*1.1,if(job='S',sal*1.2,sal)) as newsal from emp;

这个需求也可以用case…when…then…when…then…else…end来完成。

select ename,job,
case job
when 'M' then sal*1.1
when 'S' them sal*1.2
else sal
end
as sal
from emp;


cast函数:用于将值从一种数据类型转换为表达式中指定的另一种数据类型

语法:cast(值 as 数据类型)

可用的数据类型有date(日期类型),time(时间类型),datetime(日期时间类型),signed(有符号的int类型,有符号指的是正负数),char(定长字符串类型),decimal(浮点型)。

select cast(123.456 as char(4));#输出为123.
select cast(123.456 as char(3));#输出为123
select cast('1234.456' as decimal(5,1));#输出结果为1234.5.decimal(5,1)指的是保留五位有效数字,保留一位小数。


加密函数md5:可以将给定的字符串经过md5算法进行加密处理,字符串经过加密后会生成一个固定长度32位的字符串,md5加密之后的密文通常是不能解密的。


分组函数

执行原则:先分组,然后对每一组数据执行分组函数,如果没有分组语句group by的话,整张表的数据自成一组。分组函数包括:max最大值,min最小值,avg平均值,sum求和,count计数。

select max(sal) from emp;#max可替换为min,avg等分组函数


分组查询


group by

按照某个字段分组,或者按照某些字段联合分组。注意:group by的执行是在where之后执行的。

语法:

group by字段

group by字段1,字段2….

当select语句中有group by的话,select后面只能跟分组函数或参加分组的字段。例如:

select ename,deptno,avg(sal) from emp group by ename,deptno;
#正常运行,找出每个部门不同人的薪资

select ename,deptno,avg(sal) from emp group by deptno;
#报错


having

having写在group by 后面,当你对分组之后的数据不满意,可以继续通过having对分组之后的数据进行过滤。

where的过滤是在分组前进行过滤。

使用原则:尽量在where中过滤,实在不行再使用having,越早过滤效率越高。

找出除20部分之外,其他部门的平均薪资
select deptno,avg(sal) from emp where deptno<>20 group by deptno; //建议
select deptno,avg(sal) from emp group by deptno having deptno<>20; //不建议

查询每个部门平均薪资,找出平均薪资高于2k的
select deptno,avg(sal) from emp group by deptno having avg(sal)>2000;


组内排序

substring_index函数

select substring_index('http://www.baidu.com', ',' ,1);
#输出为http://www
select substring_index('http://www.baidu.com', ',' ,2);
#输出为http://www.baidu

group_concat函数

#将分组(Group By)后的多行数据合并成一个字符串。常用于将一对多关系中的“多”方数据展示在一行中。
select group_concat(empno order by sal desc) from emp group by job;


总结单表的DQL语句

select     …5

from       …1

where     …2

group by …3

having     …4

order by  …6


连接查询


从一张表中查询数据称为单表查询;从两张或更多张表中联合查询数据成为多表查询,又叫做连接查询。

(主要学SQL99)

根据连接方式的不同进行分类:

  1.内连接

        1.等值连接

        2.非等值连接

        3.自连接

  2.外连接

       1.左连接

       2.右连接

3.全连接(MySQL不学)


笛卡尔积现象

1.当两张表进行连接查询时,如果没有任何条件进行过滤,最终的查询结果条数是两张表条数的乘积。为了避免笛卡尔积现象的发生,需要添加条件进行筛选过滤。

2.需要注意:添加条件后,虽然避免了笛卡尔积现象,但是匹配的次数没有减少。

3.为了SQL语句的可读性,为了执行效率,建议给表起别名。

select e.ename,d.dname from emp e,dept d;#起别名,as省略


内连接

满足条件记录的才会出现在结果集中。


内连接之等值连接

连接时,条件为等量关系。


内连接之非等值连接


内连接之自连接

select
e.ename员工名,l.ename领导名
from
emp e
join
emp l
on
e.mgr = l.empno;


外连接

区别

找出每个员工的上级领导,要求展示所有的员工
#内连接
select e.ename 员工 l.ename 领导 from emp e join emp l on e.mgr=l.empno;
#左外连接
select e.ename 员工 l.ename 领导 from emp e left join emp l on e.mgr=l.empno;
#右外连接
select e.ename 员工 l.ename 领导 from emp l right join emp e on e.mgr=l.empno;


多张表连接

select e.ename,d.name,s.grade
from emp e
join dept d
on e.deptno=d.deptno
join salgrade s
on e.sal between s.losal and s.hisal;
#结合之前所有学的可以发现select后面是筛选目标,from后是第一张表,join第二张表on条件,然后筛选


子查询

select语句中嵌套select语句就叫子查询。

select语句可以嵌套在哪里?

 1.where后面,from后面,select后面都是可以的。

  2.exists


where后面使用子查询

找出高于平均薪资的员工姓名和薪资。
#错误示范
select ename,sal from emp where sal>avg(sal);
错误原因:where后面不能直接使用分组函数
但是可以使用子查询:
select ename,sal from rmp where sal>(select av(sal) from emp);


from后面使用子查询

#案例:找出每个部门平均工资等级。
#第一步:先找出每个部门平均工资。
select deptno ,avg(sal) avgsal from emp group by deptno;
#第二步:将以上查询结果当作临时表t,t表和salgrade表进行连接查询。
#条件:t.avgsal between s.losal and s. hisal
select t.*,s.gradenfrom(select deptno,avg(sal) avgsal from emp group by deptno) t join salgrade s on t.avgsal between s.losal and s.hisal;


select后面使用子查询

select e.ename,(select d.dname from dept d where e.deptno = d.deptno)as dname from emp e;


exists,not exists

在数据库中,EXISTS(存在)用于检查子查询的查询结果行数是否大于0.如果子查询的查询结果行数大于0,则EXISTS条件为真。(即存在查询结果限制则是TRUE)。

主要应用场景:

·EXISTS可以与SELECT,UPDATE,DELETE一起使用,用于检查另一个查询是否返回任何行;

·EXISTS可以用于验证条件子句中的表达式是否存在;

·EXISIS常用于子查询条件过滤。


in和exists区别

in和exists都是用于关系型数据库查询的操作符,不同之处在于:

1.in操作符是根据指定列表中的值来判断是否满足条件,而exists操作符则是根据子查询的结果是否有返回记录集来判断。

2.exists操作符通常比in操作符更快,尤其是在子查询返回记录数很大的情况下。因为exists只需要判断是否存在符合条件的记录,而in操作符需要比对整个列表,因此执行效率更低。

3.in操作符可同时匹配多个值,exists只能匹配一组条件。


union,union all

不管是union还是union all都可以将两个查询结果集进行合并。

union会对合并之后的查询结果集进行去重操作。

union all是直接将查询结果集合并,不进行去重操作,效率更高。


limit

作用:查询第几条到第几条的记录。通常是因为表中数据量太大,需要分页显示。

语法格式:limit 开始下标,长度

赞(0)
未经允许不得转载:171主机测评 » 数据库查询语言DQL全解析
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址