Oracle怎么用dql查,Oracle-DQL语句:查

本文详细介绍了DQL(数据查询语言)的基础知识,包括SELECT语句的使用、子查询、通配符、ORDER BY排序、DUAL表、GROUP BY和HAVING子句的应用,以及内连接、外连接、交叉连接和自然连接的概念。通过实例解析了各种查询方法,展示了DQL在多表查询和数据统计中的重要性。
摘要由CSDN通过智能技术生成

导航

我们为什么需要DQL语句?

DQL的关键词

简单查询

子查询

通配符

ORDER BY排序

DUAL表

GROUP BY子句

HAVING子句

多表联合查询

1.内连接

2.外连接

3.交叉连接

4.自然连接

EXISTS

UNION 与 UNION ALL

INTERSECT 与 MINUS

我们为什么需要DQL语句?

当我们只需要知道数据内容,但并不对数据进行操作的时候,我们就需要使用DQL语句来进行数据的查询读取(只读)。

DQL:Data Query Language 数据查询语言。

DQL的关键词

DQL的关键字只有一个,就是SELECT,但它却比DDL与DML加起来都要复杂:

关键词

作用

SELECT

查询表中数据

简单查询

通过select-from-where语句,即可查询指定表的特定数据,这也是最基础最简单的查询语句。我们以学生信息表t_student为例,该表中有五个字段:s_id,name,age,gender,classes分别记录:学生ID,学生姓名,学生年纪,学生性别,学生班级。建表:

create table t_student

(s_id number,

name varchar2(20),

age number,

gender varchar2(10),

classes varchar2(5)

);

对该表的查询示例:

select r.name,r.* from t_student r where r.s_id = 2;

其中,t_student后的r,为表取的临时别名,仅在当前sql语句中生效。别名可以为除了关键字的任意名字,主要是为了方便sql编写,不必再写一长串的表名。

r.*中的星号表示展示目标表的所有列。

子查询

子查询,就是一种嵌套查询,在很多sql语句中都可以灵活的使用。使用子查询,我们就可以把一个查询集的结果,当作一张表;也可以把查询的字段值,作为另一个查询的where筛选条件等等。有了子查询,sql更加灵活多变,可以实现更复杂的逻辑。

来个案例:请查询出比小虎年纪更大的所有学生信息。

看到这个需求,我们首先得查出小虎年纪,然后再查比该年纪更大的学生信息。可以想到用子查询一步到位~:

select * from t_student t

where t.age > (select r.age from t_student r where r.name = '小虎' );

需要注意的是,子查询与外层查询是分开的,可以看作是两步查询,及时使用了同一张表,我们应该看作是不同时间维度上的两张表。为了阅读更方便,建议将同一张表取两个不同别名,用来区分。

通配符

当我们使用模糊查询like时,常会与通配符一起使用。PL/SQL中常用的通配符有两个:

%,替代零个、一个或多个字符

_,替代一个字符

示例,查询学生名字中含有A字符的:

SELECT * FROM t_student r where r.name like '%A%';

--包括A开头和A结尾的

示例,查询学生名字的第三个字母为A的:

--前两个字符用_替代,_的地方必须有一个字符

SELECT * FROM t_student r where r.name like '__A%';

ORDER BY排序

查询结果的排序方式,往往并不方便我们查看,我们可以在查询语句结果通过order by语句,来指定字段(列)进行排序。order by默认是从小至大,再加上desc关键字,可以改为从大至小排序。例:

select r.age,r.* from t_student r where r.classes = 'A' order by r.age [desc];

[ ]中为可选项。

ORDER BY子句的目标字段可以是多个,但会一

DUAL表

当我们只想查询某些数据库的基本信息,或者是一些不需要实际存放在某张表中的数据,则可以通过Oracle提供的dual来实现。

dual表是一个实际存在的表,它只有固定的一行一列,不能用于存储数据。因为select语句必须接上from某张表,我们常常用它来换取系统时间等信息,实例:

select sysdate from dual; --获取系统时间

select to_char(sysdate,'YYYY-MM-DD hh24:mi:ss') from dual; --执行内置函数

select 666*777 from dual; --单纯进行计算

GROUP BY子句

当我们需要对某列进行分组统计时,则会使用到group by子句。

举个实际点的例子,我们想知道t_student表中,A,B,C班,分别有多少学生。如果不用group by,只能一个班一个班的查询,如下:

select count(1) from t_student r where r.classes = 'A';

select count(1) from t_student r where r.classes = 'B';

select count(1) from t_student r where r.classes = 'C';

通过这种方式也不靠谱,如果还有D班级,则会遗漏。如果在查询语句结尾,使用group by子句,则会将指定字段的所有值分组,相同的为一组来展示,需要注意的是,一单使用group by子句,则查询的列里只能为group by指定的列,或内置函数。实例:

select r.classes,count(1) from t_student r

group by r.classess;

-------------------------

查询结果为:

classess count(1)

----------- ----------

A 25

B 30

C 20

GROUP BY子句的目标字段也可以是多个。

HAVING子句

PL/SQL中提供的内置函数大多都挺好用的,方便快捷。但如果我们想对函数的计算结果进行筛选,是不可以直接在where条件中写函数并限制值的,因为在where条件里是还未查出结果的,函数得不到计算范围。

此时我们可以在where条件语句结束后,使用HAVING子句。having后也是写条件语句,与where类似,但having的条件语句可以使用对函数计算结果进行筛选了,having中的函数是对where条件的查询结果来计算的。

例如,我们只想查出班级人数大于25人的班级:

select r.classess,count(1) from t_student r

group by r.classess

having count(1) > 25;

其实having大多数情况也可以通过两层select来实现,这个案例也可以改写为:

select t.classes,t.cou

from(select r.classess,count(1) cou from t_student r group by r.classess) t

where t.cou > 25;

我们将group by的查询结果作为一张表,来进行嵌套查询。其中,由于count为关键字,所以为count(1)的列其取个别名,方便查询。我们也可以猜测一下,having的内部实现,是不是就是类似嵌套查询呢?

虽然两种方法都可以达到相同目的,但在代码可读性、性能等方面上,having更具优势,所以更推荐使用having。

多表联合查询

以上的内容中,都是对一张表进行的查询,但实际数据库中总是会设计很多表,多张表之前也会有许多关联关联关系,我们常常会需要用到多表的联合查询。

除了上面提到的t_student学生信息表外,我们再建一个学生的考试分数表t_score,字段有三个:s_id,score,course,分别记录:学生ID,得分,课程。建表:

create table t_score

(s_id number,

score number,

course varchar2(20)

);

1.内连接

有着主外键关联关系,并不一定需要有外键约束,只要逻辑上有着值相等的列,根据这个列建立起来的等值连接,被称为内连接,或简单连接。

示例的t_student表和t_score表中s_id字段就是主外键关系,虽然没有外键约束,我们可以建立内连接来进行查询:

select r.name,t.score,t.course from t_student r,t_score t where r.s_id = t.s_id;

2.外连接

内连接的这个案例,正常场景下,用这样的连接查询就可以查出想要的结果了。但做程序开发,往往重点就在于全面考虑异常情况。来个异常例子:如果一名学生缺考了,那t_score表中就没有他的s_id对应数据,内连接则无法查出缺考的场景数据。

对于一张表中数据是全的,另一张表中数据可能有缺失的情况,就可以使用外连接来查询。使用(+)来表示外连接,语法格式如下:

--右外连接

select table1.column,table2.column

from table1 , table2

where table1.column(+) = table2.column;

--左外连接

select table1.column,table2.column

from table1 , table2

where table1.column = table2.column(+);

右外连接:(+)在等号左边,返回table2表所有数据,right jioin

左外连接:(+)在等号右边,返回table1表所有数据,left jioin

别被这个左右绕晕了,总之就是,(+)出现在哪个表字段后面,就表示这边表的字段可能不完全,需要被(+)补充一下的意思。

有了外连接,那么对于上面提到的异常缺考情况,我们可以通过该实例查出来:

select r.s_id,r.name,t.score,t.course from t_student r,t_score t

where r.s_id = t.s_id(+);

如果学生缺考,则t_student表中的name等字段数据还是可以查出来,但对应t_score表的t.score,t.course则会为NULL空。

3.交叉连接

交叉连接是指两张表的数据行相乘得到的笛卡尔积,在where条件后不对两张表进行关联,则会产生交叉连接。如:

select r.*,t.* from t_student r,t_score t;

得到的结果集数量是两张表行数的乘积,且由于每行缺少有意义的关联关系,结果集也失去了意义。

4.自然连接

自然连接是内连接的严格要求后的升级版,如果两张表有着相同名字的字段,且数据类型也相同,那么可以使用natural join来让他们自然连接,示例:

select * from t_student natural join t_score;

但实际过程中一般不使用,还是采用内连接方式逻辑更清晰,提高代码可读性。

EXISTS

来一个案例:请查询出缺考语文科目学生的学生信息。

该例子中需要的结果只是学生信息,即t_student表,但学生是否缺考我们需要根据t_score成绩表才知道。如何实现不在from中添加t_score表,但在where中却可以将t_score表作为条件限制呢?。使用exists语句,则可以办到。

exists是存在的意思,它后面接一个子查询,如果该子查询能查到结果集,则条件成立。not exists则是不存在,如果后面的子查询查不到结果集,条件才成立。

查询缺考学生信息实例:

select * from t_student r

where not exists(select 1 from t_score t where r.s_id = t.s_id and t.course = '语文');

UNION 与 UNION ALL

我们称每个查询语句的结果为结果集,如果多个结果集的列名和列数据类型一致的话,可以使用union或union all来合并,及取并集。

如果我们有一张学生信息历史表t_student_history,记录了学生以前的信息。现在有一个需求,需要同时展示t_student与t_student_history中,s_id为1的数据。此使,就可以使用union来实现:

select s_id,name,age,gender,classes from t_student where s_id = 1

union

select s_id,name,age,gender,classes from t_student_history where s_id = 1;

被union的结果集,列名、数据类型、顺序均相同,才可以编译通过,成功合并两个结果集的查询结果。该案例中,如果历史表中的数据,与当前表数据一模一样,则会被消除,完全相同的数据无论多少后,最后只保留一行。

而union all与union基本一样,主要的区别是union all不会消除重复数据,而是全部保留。

INTERSECT 与 MINUS

有取并集的方法,那就少不了取交集和差集嘛,来就来全套~

intersect,是取交集,只会得到两个结果集数据相同的部分。

minus,是取差集,会得到除去两个结果集数据相同的部分后的数据。

语法与union相同,写在两个select中间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值