百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT技术 > 正文

从零开始学习Oracle之查询数据

wptr33 2025-02-07 19:21 25 浏览

数据库管理系统的一个最重要的功能就是数据查询,数据查询不应只是简单返回数据库中存储的数据,还应该根据需要对数据进行筛选,以及确定数据以什么样的格式显示。Oracle提供了功能强大、灵活的语句来实现这些操作。

1.基本查询语句

Oracle从数据表中查询数据的基本语句为SELECT语句。SELECT语句的基本格式是:

SELECT
      {* | <字段列表>}
      [
          FROM <表1>,<表2>...
          [WHERE <表达式>]
          [GROUP BY ]
          [HAVING  [{ }...]]
          [ORDER BY ]
          [LIMIT [,] ]
      ]
      
SELECT [字段1,字段2,…,字段n]
FROM [表或视图]
WHERE [查询条件];
  • {* | <字段列表>}包含星号通配符选字段列表,表示查询的字段,其中字段列至少包含一个字段名称,如果要查询多个字段,多个字段之间用逗号隔开,最后一个字段后不要加逗号。
  • FROM<表1>,<表2>..,表1和表2表示查询数据的来源,可以是单个或者多个。
  • WHERE子句是可选项,限定查询行必须满足的查询条件。
  • GROUP BY <字段>,该子句告诉 Oracle如何显示查询出来的数据,并按照指定的字段分组。
  • ORDER BY <字段>,该子句告诉Oracle按什么样的顺序显示查询出来的数据,可以进行的排序有:升序(ASC)、降序(DESC)。
  • LIMIT [,] ,该子句告诉Oracle每次显示查询出来的数据条数。

2.单表查询

单表查询是指从一张数据表中查询所需的数据。单表查询中的各种基本的查询方式,主要有:查询所有字段、查询指定字段、查询指定记录、查询空值、多条件查询、对查询结果进行排序等。

2.1查询所有字段

在SELECT语句中使用星号”*”通配符查询所有字段;

SELECT * FROM 表名;

注意:一般情况下,除非需要使用表中所有的字段数据,最好不要使用通配符“*”。使用通配符虽然可以节省输入查询语句的时间,但是获取不需要的列数据通常会降低查询和所使用的应用程序的效率。通配符的优势是,当不知道所需要的列的名称时,可以通过它获取它们。

2.2查询指定字段

查询表中的某一个字段,语法格式为:

SELECT 列名 FROM 表名;

查询多个字段,语法格式为:

SELECT 字段名1,字段名2,…,字段名n FROM 表名;

注意:Oracle中的SQL语句是不区分大小写的,因此SELECT和select作用是相同的,但是,许多开发人员习惯将关键字使用大写,而数据列和表名使用小写,读者也应该养成一个良好的编程习惯,这样写出来的代码更容易阅读和维护。

2.3查询指定记录

数据库中包含大量的数据,根据特殊要求,可能只需要查询表中的指定数据,即对数据进行过滤。在SELECT 语句中,通过WHERE子句可以对数据进行过滤,语法格式为:

SELECT 字段名1,字段名2,…,字段名n
FROM 表名
WHERE 查询条件

2.4带IN关键字的查询

IN操作符用来查询满足指定范围内的条件的记录,使用IN操作符,将所有检索条件用括号括起来,检索条件之间用逗号分隔开,只要满足条件范围内的一个值即为匹配项。相反的,可以使用关键字NOT来检索不在条件范围内的记录。

2.5带BETWEEN AND的范围查询

BETWEENAND用来查询某个范围内的值,该操作符需要两个参数,即范围的开始值和结束值,如果字段值满足指定的范围查询条件,则这些记录被返回。BETWEEN匹配范围中所有值,包括开始值和结束值。

BETWEEN AND操作符前可以加关键字NOT,表示指定范围之外的值,如果字段值不满足指定的范围内的值,则这些记录被返回。

2.6带LIKE的字符匹配查询

通配符是一种在SQL的WHERE条件子句中拥有特殊意思的字符,SQL语句中支持多种 通配符,可以和LIKE一起使用的通配符有“%”和“_”。

  • 百分号通配符“%”,匹配任意长度的字符,甚至包括零字符;
  • 下划线通配符“_”,一次只能匹配任意一个字符。

2.7查询空值

创建数据表的时候,设计者可以指定某列中是否可以包含空值(NULL)。空值不同于0,也不同于空字符串。空值一般表示数据未知、不适用或将在以后添加数据。在SELECT语句中使用IS NULL子句,可以查询某字段内容为空记录。与IS NULL相反的是NOT IS NULL,该关键字查找字段不为空的记录。

2.8带AND的多条件查询

使用SELECT查询时,可以增加查询的限制条件,这样可以使查询的结果更加精确。Oracle在WHERE子句中使用AND操作符限定只有满足所有查询条件的记录才会被返回。可以使用AND连接两个甚至多个查询条件,多个条件表达式之间用AND分开。

2.9带OR的多条件查询

与AND相反,在WHERE声明中使用OR操作符,表示只需要满足其中一个条件的记录 即可返回。OR也可以连接两个甚至多个查询条件,多个条件表达式之间用OR分开。 OR操作符和IN操作符使用后的结果是一样的,它们可以实现相同的功能。但是,IN操作符使得检索语句更加简洁明了,并且IN执行的速度要快于OR。

注意:OR可以和AND一起使用,但是在使用时要注意两者的优先级,由于AND的优先级高于OR,因此先对AND两边的操作数进行操作,再与OR中的操作数结合。

2.10查询结果不重复

在SELECT语句中,可以使用DISTINCT关键字指示Oracle消除重复的记录值。语法格式为:

SELECT DISTINCT 字段名 FROM 表名;

2.11对查询结果排序

Oracle可以通过在SELECT语句中使用ORDER BY子句,对查询的结果进行排序。

  • ORDER BY 字段 或者 ORDER BY 字段 ASC 按字段进行升序排序
  • ORDER BY 字段 DESC 按字段进行降序排序
  • 如对多列进行排序,将字段用逗号隔开即可:ORDER BY 字段1,字段2,...字段n

在对多列进行排序的时候,首先排序的第一列必须有相同的列值,才会对第二列进行排序。如果第一列数据中所有值都是唯一的,将不再对第二列进行排序。

2.12分组查询

分组查询是对数据按照某个或多个字段进行分组,Oracle中使用GROUP BY关键字对数据进行分组,基本语法形式为:

[GROUP BY字段] [HAVING <条件表达式>]

其中,“字段”为进行分组时所依据的列名称;“HAVING <条件表达式>”指定满足表 达式限定条件的结果将被显示。

GROUP BY关键字通常和集合函数一起使用,如MAX()、MIN()、COUNT()、SUM()、AVG()。

Oracle 可以在GROUP BY子句中使用LISTAGG()函数,将每个分组中各个字段的值显示出来。

GROUP BY可以和HAVING一起限定显示记录所需满足的条件,只有满足条件的分组才会被显示。

注意:HAVING关键字与WHERE关键字都可以用来过滤数据,两者的区别是:HAVING在数据分组之后进行过滤来选择分组,而WHERE在分组之前用来选择记录。另外,WHERE排除的记录不再包括在分组中。

在GROUP BY子句中使用ROLLUP关键字之后,在所有查询出的分组记录之后增加一条记录,该记录计算查询出的所有记录的总和,即统计记录数量。

使用GROUP BY可以对多个字段进行分组,GROUP BY关键字后面跟需要分组的字段,Oracle根据多字段的值来进行层次分组,分组层次从左到右,即先按第1个字段分组,然后在第1个字段值相同的记录中,再根据第2个字段的值进行分组,……,依此类推。

当使用ROLLUP时,不能同时使用ORDER BY子句进行结果排序,即ROLLUP和ORDER BY是互相排斥的。

2.13使用ROWNUM限制查询结果的数量

SELECT返回所有匹配的行,有可能是表中所有的行,如果仅需要返回第一行或者前几行,则可以使用ROWNUM来限制。

注意:使用ROWNUM时,只支持<、<=和!=符号,不支持>、>=、=和BETWEEN...AND符号

3.使用聚合函数查询

有时候并不需要返回实际表中的数据,而只是对数据进行总结。Oracle提供一些查询功能,可以对获取的数据进行分析和报告。这些函数的功能有:计算数据表中记录行数的总数、计算某个字段列下数据的总和,以及计算表中某个字段下的最大值、最小值或者平均值。

3.1 COUNT()函数

COUNT()函数统计数据表中包含的记录行的总数,或者根据查询结果返回列中包含的数据行数。其使用方法有两种:

  • COUNT(*)计算表中总的行数,不管某列是否有空值。
  • COUNT(字段名)计算指定列下总的行数,计算时将忽略空值的行。

3.2 SUM()函数

SUM()是一个求总和的函数,返回指定列值的总和。

SUM()可以与GROUP BY一起使用,用来计算每个分组的总和。

SUM()函数在计算时,忽略列值为NULL的行。

3.3 AVG()函数

AVG()函数通过计算返回的行数和每一列数据的和,求得指定列数据的平均值。

AVG()可以与GROUP BY一起使用,用来计算每个分组的平均值。

AVG()函数使用时,其参数为要计算的列名称,如果要得到多个列的多个平均值,则需要在每一列上使用AVGO函数。

3.4 MAX()函数

MAX()返回指定列中的最大值。

MAX()也可以和GROUP BY关键字一起使用,求每个分组中的最大值。

MAX()函数不仅适用于查找数值类型,也可应用于字符类型。

3.5 MIN()函数

MIN()返回查询列中的最小值。

MIN()也可以和GROUP BY关键字一起使用,求出每个分组中的最小值。

MIN()函数与MAX()函数类似,不仅适用于查找数值类型,也可应用于字符类型。

4.连接查询

连接查询是关系数据库中最主要的查询,主要包括内连接、外连接等。通过连接运算符可以实现多个表查询。在关系数据库管理系统中,建立表时各数据之间的关系不必确定,常把一个实体的所有信息存放在一个表中。当查询数据时,通过连接操作查询出存放在多个表中的不同实体的信息。当两个或多个表中存在相同意义的字段时,便可以通过这些字段对不同的表进行连接查询。

4.1内连接查询

内连接(INNER JOIN)使用比较运算符进行表间某(些)列数据的比较操作,并列出这些表中与连接条件相匹配的数据行,组合成新的记录。也就是说,在内连接查询中,只有满足条件的记录才能出现在结果关系中。

如果在一个连接查询中,涉及的两个表都是同一个表,这种查询称为自连接查询。自连接是一种特殊的内连接,它是指相互连接的表在物理上为同一张表,但可以在逻辑上分为两张表。

SELECT column_name(s)
FROM table1
INNER JOIN table2
ON table1.column_name=table2.column_name;
--或者
SELECT column_name(s)
FROM table1
JOIN table2
ON table1.column_name=table2.column_name;

INNER JOIN 与 JOIN 是相同的,取的是两个表的并集。

4.2外连接查询

连接查询将查询多个表中相关联的行,内连接时,返回查询结果集合中的仅是符合查询条件和连接条件的行。但有时候需要包含没有关联的行中的数据,即返回查询结果集合中的不仅包含符合连接条件的行,而且还包括左表(左外连接或左连接)、右表(右外连接或右连接)或两个边接表(全外连接)中的所有数据行。外连接分为左外连接和右外连接。

  • LEFT JOIN(左连接):返回包括左表中的所有记录和右表中连接字段相等的记录。
  • RIGHT JOIN(右连接):返回包括右表中的所有记录和右表中连接字段相等的记录。
SELECT column_name(s)
FROM table1
LEFT JOIN table2
ON table1.column_name=table2.column_name;

SELECT column_name(s)
FROM table1
RIGHT JOIN table2
ON table1.column_name=table2.column_name;

4.3复合条件连接查询

复合条件连接查询是在连接查询的过程中,通过添加过滤条件,限制查询的结果,使查询的结果更加准确。

5.子查询

子查询指一个查询语句嵌套在另一个查询语句内部的查询,在SELECT子句中先计算子查询,子查询结果作为外层另一个查询的过滤条件,查询可以基于一个表或者多个表。子查询中常用的操作符有ANY(SOME)、ALL、IN、EXISTS。子查询可以添加到SELECT、UPDATE和DELETE语句中,而且可以进行多层嵌套。子查询中也可以使用比较运算符,如“<”、“<=”、“>”、“>=”和“!=”等。

5.1带ANY、SOME关键字的子查询

ANY和SOME关键字是同义词,表示满足其中任一条件,它们允许创建一个表达式对子查询的返回值列表进行比较,只要满足内层子查询中的任何一个比较条件,就返回一个结果作为外层查询的条件。

ANY关键字接在一个比较操作符的后面,表示若与子查询返回的任何值比较为TRUE,则返回TRUE。

SELECT numl FROM table1 WHERE
num1 > ANY (SELECT num2 FROM table2);

上面SQL语句的意思是将table1中的num1与ANY后的子查询查出的table2中的num2进行比较,显示num1>num2的结果。

5.2带ALL关键字的子查询

ALL关键字与ANY和SOME不同,使用ALL时需要同时满足所有内层查询的条件。

ALL 关键字接在一个比较操作符的后面,表示若与子查询返回的所有值比较为TRUE,则返回TRUE。

SELECT numl FROM table1 WHERE
num1 > ALL (SELECT num2 FROM table2);

上面SQL语句的意思是将table1中的num1与ALL后的子查询查出的table2中的num2的所有值进行进行比较,显示大于所有num2列值的num1。

5.3带EXISTS关键字的子查询

EXISTS关键字后面的参数是一个任意的子查询,系统对子查询进行运算以判断它是否返回行,如果至少返回一行,那么EXISTS的结果为TRUE,此时外层查询语句将进行查询;如果子查询没有返回任何行,那么EXISTS 返回的结果是FALSE,此时外层查询语句将不进行查询。

NOT EXISTS与EXISTS使用方法相同,返回的结果相反。子查询如果至少返回一行,那么NOT EXISTS的结果为FALSE,此时外层查询语句将不进行查询;如果子查询没有返回任何行,那么NOTEXISTS返回的结果是TRUE,此时外层语句将进行查询。

EXISTS和NOTEXISTS的结果只取决于是否会返回行,而不取决于这些行的内容,所以这个子查询输入列表通常是无关紧要的。

SELECT numl FROM table1 WHERE
num1 > EXISTS (SELECT num2 FROM table2 where num2=1);

上面SQL语句的意思是查询table2中num2列是否存在为1的值,如果存在则执行table1的查询语句,如果不存在,则不执行 EXISTS 之前的查询语句。

5.4带IN关键字的子查询

IN关键字进行子查询时,内层查询语句仅仅返回一个数据列,这个数据列里的值将提供给外层查询语句进行比较操作。

SELECT语句中可以使用NOT IN关键字,其作用与IN正好相反。

SELECT numl FROM table1 WHERE
num1 in (SELECT num2 FROM table2);

6.合并查询结果

利用UNION关键字,可以给出多条SELECT语句,并将它们的结果组合成单个结果集。合并时,两个表对应的列数和数据类型必须相同。各个SELECT 语句之间使用UNION 或UNION ALL关键字分隔。UNION不使用关键字ALL,执行的时候删除重复的记录,所有返回的行都是唯一的;使用关键字ALL的作用是不删除重复行也不对结果进行自动排序。基本语法如下:

SELECT column,... FROM tablel
UNION [ALL]
SELECT column,... FROM table2

UNION从查询结果集中自动去除了重复的行,如果要返回所有匹配行,而不进行删 除,可以使用UNION ALL。

UNION和UNION ALL的区别:使用UNION ALL的功能是不删除重复行,加上ALL关 键字语句执行时所需要的资源少,所以尽可能地使用它,因此知道有重复行但是想保留这些行,确定查询结果中不会有重复数据或者不需要去掉重复数据的时候,应当使用UNION ALL以提高查询效率。

7.为表和字段取别名

当表名字很长或者执行一些特殊查询时,为了方便操作或者需要多次使用相同的表时,可以为表指定别名,用这个别名替代表原来的名称。为表取别名的基本语法格式为:

表名 [AS] 表别名

Oracle 可以指定列别名,替换字段或表达式。为字段取别名的基本语法格式为:

列名 [AS] 列别名

表别名只在执行查询的时候使用,并不在返回结果中显示,而列别名定义之后,将返回给客户端显示,显示的结果字段为字段列的别名。

8.使用正则表达式查询

正则表达式通常被用来检索或替换那些符合某个模式的文本内容,根据指定的匹配模式匹配文本中符合要求的特殊字符串。例如,从一个文本文件中提取电话号码,查找一篇文章中重复的单词或者替换用户输入的某些敏感词语等,这些地方都可以使用正则表达式。正则表达式强大而且灵活,可以应用于非常复杂的查询。

Oracle中使用REGEXP LIKEO函数指定正则表达式的字符匹配模式,下表列出了 REGEXP LIKE函数中常用字符匹配列表。

--查询表中name列以字母b开头的数据
SELECT * FROM table WHERE REGEXP_LIKE(name , '^b');

相关推荐

高性能并发队列Disruptor使用详解

基本概念Disruptor是一个高性能的异步处理框架,是一个轻量的Java消息服务JMS,能够在无锁的情况下实现队列的并发操作Disruptor使用环形数组实现了类似队列的功能,并且是一个有界队列....

Disruptor一个高性能队列_java高性能队列

Disruptor一个高性能队列前言说到队列比较熟悉的可能是ArrayBlockingQueue、LinkedBlockingQueue这两个有界队列,大多应用在线程池中使用能保证线程安全,但其安全性...

谈谈防御性编程_防御性策略

防御性编程对于程序员来说是一种良好的代码习惯,是为了保护自己的程序在不可未知的异常下,避免带来更大的破坏性崩溃,使得程序在错误发生时,依然能够云淡风轻的处理,但很多程序员入行很多年,写出的代码依然都是...

有人敲门,开水开了,电话响了,孩子哭了,你先顾谁?

前言哎呀,这种情况你肯定遇到过吧!正在家里忙活着,突然——咚咚咚有人敲门,咕噜咕噜开水开了,铃铃铃电话响了,哇哇哇孩子又哭了...我去,四件事一起来,人都懵了!你说先搞哪个?其实这跟我们写Java多线...

面试官:线程池如何按照core、max、queue的执行顺序去执行?

前言这是一个真实的面试题。前几天一个朋友在群里分享了他刚刚面试候选者时问的问题:"线程池如何按照core、max、queue的执行循序去执行?"。我们都知道线程池中代码执行顺序是:co...

深入剖析 Java 中线程池的多种实现方式

在当今高度并发的互联网软件开发领域,高效地管理和利用线程资源是提升程序性能的关键。Java作为一种广泛应用于后端开发的编程语言,为我们提供了丰富的线程池实现方式。今天,就让我们深入探讨Java中...

并发编程之《彻底搞懂Java线程》_java多线程并发解决方案详解

目录引言一、核心概念:线程是什么?...

Redis怎么实现延时消息_redis实现延时任务

一句话总结Redis可通过有序集合(ZSET)实现延时消息:将消息作为value,到期时间戳作为score存入ZSET。消费者轮询用ZRANGEBYSCORE获取到期消息,配合Lua脚本保证原子性获取...

CompletableFuture真的用对了吗?盘点它最容易被误用的5个场景

在Java并发编程中,CompletableFuture是处理异步任务的利器,但不少开发者在使用时踩过这些坑——线上服务突然雪崩、异常悄无声息消失、接口响应时间翻倍……本文结合真实案例,拆解5个最容易...

接口性能优化技巧,有点硬_接口性能瓶颈

背景我负责的系统到2021年初完成了功能上的建设,开始进入到推广阶段。随着推广的逐步深入,收到了很多好评的同时也收到了很多对性能的吐槽。刚刚收到吐槽的时候,我们的心情是这样的:...

禁止使用这5个Java类,每一个背后都有一段&quot;血泪史&quot;

某电商平台的支付系统突然报警:大量订单状态异常。排查日志发现,同一笔订单被重复支付了三次。事后复盘显示,罪魁祸首竟是一行看似无害的SimpleDateFormat代码。在Java开发中,这类因使用不安...

无锁队列Disruptor原理解析_无锁队列实现原理

队列比较队列...

Java并发队列与容器_java 并发队列

【前言:无论是大数据从业人员还是Java从业人员,掌握Java高并发和多线程是必备技能之一。本文主要阐述Java并发包下的阻塞队列和并发容器,其实研读过大数据相关技术如Spark、Storm等源码的,...

线程池工具及拒绝策略的使用_线程池处理策略

线程池的拒绝策略若线程池中的核心线程数被用完且阻塞队列已排满,则此时线程池的资源已耗尽,线程池将没有足够的线程资源执行新的任务。为了保证操作系统的安全,线程池将通过拒绝策略处理新添加的线程任务。...

【面试题精讲】ArrayBlockingQueue 和 LinkedBlockingQueue 区别?

有的时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,认准...