PL/SQL

PL/SQL 知识量:16 - 57 - 244

5.3 带条件的查询><

单一的条件查询- 5.3.1 -

一个数据表中存放着大量相关的记录数据,在实际使用时,往往只需要其中满足要求的部分记录,这时就需要用到WHERE条件子句。语法格式如下:

SELECT  列名1[,列名2,…列名n]
FROM    表名
WHERE   条件

使用WHERE子句可以限制查询的范围,提高查询效率。在使用时,WHERE子句必须紧跟在FROM子句后面。WHERE子句中的条件表达式包括算术表达式和逻辑表达式两种,WHERE子句中查询条件的数目没有限制。

下面示例查询people表中性别是“male”的人员信息:

SQL> select * from people where sex='male';

  ID NAME        AGE SEX    HEIGHT WEIGHT
---- ---------- ---- ------ ------ ------
   1 Bob          25 male      170     70
   2 Jeff         27 male      176     82
   5 Tom          29 male      188     95
   7 Tomas        32 male      166     60

查询中使用比较表达式- 5.3.2 -

在WHERE子句中,可以使用比较表达式作为搜索条件。表达式可以为常量、变量和列表达式的任意有效组合。

在WHERE子句中允许使用的比较运算符包括:

  • =(等于):表示查询出列的数据要和提供的数据相等。

  • <(小于):表示查询出列的数据要小于提供的数据。

  • >(大于):表示查询出列的数据要大于提供的数据。

  • <>(不等于):表示查询出列的数据和提供的数据不能相同。

  • !=(不等于):和“<>”起相同的作用。

  • <=(小于等于):表示查询出列的数据要小于或等于提供的数据。

  • >=(大于等于):表示查询出列的数据要大于或等于提供的数据。

下面示例查询people表中年龄小于30的人员信息:

SQL> select * from people where age<30;

  ID NAME        AGE SEX    HEIGHT WEIGHT
---- ---------- ---- ------ ------ ------
   1 Bob          25 male      170     70
   2 Jeff         27 male      176     82
   4 Susan        19 female    168     55
   5 Tom          29 male      188     95
   6 Lucy         29 female    168     65

除了可以对数值类型的字段使用比较运算符外,对于字符串类型的字段也可以使用比较运算符。

对于如“>”、“>=”、“<”等比较运算符,是根据字符的排列顺序比较的。字符串的排序是根据其首字母的顺序进行的,如果首字符相同,则比较其下一个字符,依此类推。

对于汉字的排序,是根据其汉语拼音的第一个字母的顺序进行的,如果第1个字母相同,则比较第2个字母,依此类推,且汉字的顺序要高于字母的顺序。

SQL> select * from people where name >= 'S';

  ID NAME        AGE SEX    HEIGHT WEIGHT
---- ---------- ---- ------ ------ ------
   4 Susan        19 female    168     55
   5 Tom          29 male      188     95
   7 Tomas        32 male      166     60

使用简单逻辑表达式- 5.3.3 -

在WHERE子句中,可以使用多个搜索条件选择记录(行),即通过逻辑运算符(NOT、AND或OR)将多个单独的搜索条件结合在一个WHERE子句中,形成一个复合的搜索条件。

当对复合的搜索条件求值时,数据库管理系统会对每个单独的搜索条件求值,然后执行布尔运算来决定整个WHERE子句的值是TRUE还是FALSE。只有那些满足整个WHERE子句的值是TRUE的记录才出现在结果表中。

1、AND运算符。AND运算符表示逻辑“与”的关系。当使用AND运算符组合两个逻辑表达式时,只有当两个表达式均为TRUE时才返回TRUE。

下面示例查询年龄大于20且性别是“female”的人员信息:

SQL> select * from people where age>20 and sex='female';

  ID NAME        AGE SEX    HEIGHT WEIGHT
---- ---------- ---- ------ ------ ------
   3 Jan          32 female    166     52
   6 Lucy         29 female    168     65

2、OR运算符。OR运算符实现逻辑“或”的运算关系。当使用OR运算符组合两个逻辑表达式时,只要其中一个表达式的条件为TRUE,结果便返回TRUE。

下面示例查询年龄大于30或性别是“male”的人员信息:

SQL> select * from people where age>30 or sex='male';

  ID NAME        AGE SEX    HEIGHT WEIGHT
---- ---------- ---- ------ ------ ------
   1 Bob          25 male      170     70
   2 Jeff         27 male      176     82
   3 Jan          32 female    166     52
   5 Tom          29 male      188     95
   7 Tomas        32 male      166     60

3、NOT运算符。NOT运算符实现逻辑“非”的运算关系,用于对搜索条件的逻辑值求反。

下面示例查询性别不是“male”的人员信息:

SQL> select * from people where not sex='male';

  ID NAME        AGE SEX    HEIGHT WEIGHT
---- ---------- ---- ------ ------ ------
   3 Jan          32 female    166     52
   4 Susan        19 female    168     55
   6 Lucy         29 female    168     65

注意:NOT NULL的结果仍为NULL。

4、AND、OR、NOT的组合使用。在WHERE子句中,各种逻辑运算符可以组合使用,即AND、OR、NOT运算符可以同时使用。与使用算术运算符进行运算一样,使用逻辑运算符也存在运算的优先级问题。NOT运算符的优先级最高,而后是AND,最后是OR。

下面示例查询性别不是“male”且年龄大于20的人员或姓名为“Bob”的人员信息:

SQL> select * from people where not sex='male' and age>20 or name='Bob';

  ID NAME        AGE SEX    HEIGHT WEIGHT
---- ---------- ---- ------ ------ ------
   1 Bob          25 male      170     70
   3 Jan          32 female    166     52
   6 Lucy         29 female    168     65

有关NULL值的判断- 5.3.4 -

除非在创建时指定了NOT NULL约束,否则数据库表中某些列的值可以为NULL。

NULL就是空,在数据库中,含有空值的表的列长度为零。

NULL与0、空字符串、空格都不同,它等价于没有任何值,是未知数。然而,NULL却是一个数据值,而且它属于一个域。例如一个字符串字段,其中的NULL只能是一个字符串。尽管它的内容没有定义,或者未知,但它是字符串。

对于NULL,一般的运算,比如加、减、乘、除都会返回NULL。永远不会有什么数据等于NULL。注意:NULL也不等于NULL,说一个NULL等于NULL是错误的。

在SQL中如果出现表达式“X IS NULL”,那么当X是NULL时,就返回TRUE;如果X不为NULL时,则返回FALSE。因此,在WHERE子句中,判断一个值是否为NULL,只能采用IS [NOT] NULL判别式。

注意:X IS NULL不可以写成X=NULL;除了IS [NOT] NULL之外,空值不满足任何查找条件;如果NULL参与算术运算,则该算术表达式的值为NULL;如果NULL参与聚集运算,则除count(*)之外其他聚集函数都忽略NULL。

模糊查询- 5.3.5 -

模糊查询是指根据一些并不确切的线索来搜索信息。PL/SQL提供了LIKE子句来进行这类模糊查询。在大多数情况下,LIKE子句会与通配符配合使用。PL/SQL中提供了2个通配符供用户灵活地实现复杂的模糊查询条件:

  • _:可以替代一个字符。

  • %:可以替代个数不确定的字符。

1、“_”通配符。

“_”通配符只能匹配任何单个字符。比如,“_n”表示将查询以“n”结尾的所有2个字母的字符串(如“an”、“cn”、“en”等)。当然,要表示两个字符的匹配,就需要使用两个“_”通配符,即写成“__”即可。

只有在用户确定所要查询的字符串的个数,只是不确定其中的一个或几个字符的确切值时,才能使用“_”通配符。

使用“_”通配符的示例如下:

SQL> select * from people where age like '_9';

  ID NAME        AGE SEX    HEIGHT WEIGHT
---- ---------- ---- ------ ------ ------
   4 Susan        19 female    168     55
   5 Tom          29 male      188     95
   6 Lucy         29 female    168     65

2、“%”通配符。

“%”通配符和“_”通配符不同,它表示任意字符的匹配,且不计字符的多少。如“a%”表示匹配以字符串“a”开头的任意字符串;“%a”表示匹配以字符串“a”结尾的任意字符串;“%a%”表示匹配含有字符串“a”的任意字符串。

使用“%”通配符的示例如下:

SQL> select * from people where name like '%a%';

  ID NAME        AGE SEX    HEIGHT WEIGHT
---- ---------- ---- ------ ------ ------
   3 Jan          32 female    166     52
   4 Susan        19 female    168     55
   7 Tomas        32 male      166     60

注意:虽然数据库中对字段或关键词的大小写不加区分,但表中的数据记录是区分大小写的。

指定数据范围- 5.3.6 -

在WHERE子句中,使用BETWEEN关键词可以更方便地限制查询数据的范围。当然,还可以使用NOT BETWEEN关键词查询限定数据范围之外的记录。其语法格式如下:

表达式[NOT] BETWEEN 表达式1 AND 表达式2

简要说明:

  • 表达式:待指定范围的表达式。

  • 表达式1:限定范围的起始。

  • 表达式2:限定范围的结束。

下面示例查询年龄介于20岁至30岁之间的人员信息:

SQL> select * from people where age between 20 and 30;

  ID NAME        AGE SEX    HEIGHT WEIGHT
---- ---------- ---- ------ ------ ------
   1 Bob          25 male      170     70
   2 Jeff         27 male      176     82
   5 Tom          29 male      188     95
   6 Lucy         29 female    168     65

注意:使用BETWEEN限制查询数据范围时同时包括了边界值,而使用NOT BETWEEN进行查询时没有包括边界值。因此,使用BETWEEN表达式进行查询的效果完全可以用含有“>=”和“<=”的逻辑表达式来代替,使用NOT BETWEEN进行查询的效果完全可以用含有“>”和“<”的逻辑表达式来代替。

限制检索数据范围- 5.3.7 -

同BETWEEN关键词一样,IN的引入也是为了更方便地限制检索数据的范围,灵活地使用IN关键词,可以用简洁的语句实现结构复杂的查询。其语法格式如下:

表达式 [NOT]  IN  (表达式1 , 表达式2 [,…表达式n])

简要说明:

  • 表达式:待指定范围的表达式。

  • 表达式1:代表某个具体含义的表达式。

  • 表达式2:代表某个具体含义的表达式。

  • 括号中允许有N个表达式,即允许有N个值,然后待指定范围的表达式会根据括号中的参数一一进行查询。

所有的条件在IN运算符后面罗列,并以括号( )包括起来,条件中间用逗号分开。当要判断的表达式处于括号中列出的一系列值之中时,IN运算符求值为TRUE。

SQL> select * from people where age in(25,26,27,28,29);

  ID NAME        AGE SEX    HEIGHT WEIGHT
---- ---------- ---- ------ ------ ------
   1 Bob          25 male      170     70
   2 Jeff         27 male      176     82
   5 Tom          29 male      188     95
   6 Lucy         29 female    168     65

在大多数情况下,OR运算符与IN运算符可以实现相同的功能。例如以上示例可以改写为:

SQL> select * from people where age=25 or age=26 or age=27 or age=28 or age=29;

  ID NAME        AGE SEX    HEIGHT WEIGHT
---- ---------- ---- ------ ------ ------
   1 Bob          25 male      170     70
   2 Jeff         27 male      176     82
   5 Tom          29 male      188     95
   6 Lucy         29 female    168     65

IN运算符与OR运算符可以实现相同的功能,然而使用IN运算符更为简洁,特别是当选择的条件很多时,只需在括号内用逗号分隔各条件即可,其运行效率也比OR运算符要高。另外,使用IN运算符,其后面所有的条件可以是另一条SELECT语句,即子查询。

下面示例首先查询体重介于65至85之间的人员的年龄,然后查询年龄属于第一步查询结果内的人员信息:

SQL> select * from people where age in(select age from people where weight between 65 and 85);

  ID NAME        AGE SEX    HEIGHT WEIGHT
---- ---------- ---- ------ ------ ------
   1 Bob          25 male      170     70
   2 Jeff         27 male      176     82
   5 Tom          29 male      188     95
   6 Lucy         29 female    168     65

定义转义符- 5.3.8 -

在使用PL/SQL进行数据查询时,在某种情况下会遇到特殊字符的问题,例如使用LIKE进行模糊查询时,当“%”和“_”符号单独出现时,就会被认为是通配符。但有时可能需要搜索包含一个或多个特殊通配符的字符串,例如,数据库表中可能存储含百分号(%) 的折扣值。若要搜索作为字符而不是通配符的百分号,必须提供ESCAPE关键词和转义符。相关语法如下:

ESCAPE 'escape_character'

简要说明:

  • 以上表达式表示在字符串中搜索通配符,但不将其作为通配符使用。ESCAPE是关键字。

  • escape_character是指要转换的通配符,escape_character后面的通配符失去通配符的意义,而是表示普通的字符。

示例查询表books中name中含有“_”的所有书籍信息:

SQL> select * from books;

        ID NAME            PRICE
---------- ---------- ----------
         1 CSS                32
         2 Java_1             38
         3 Java_2             40
         4 SQL                25
         5 Python             55

SQL> select * from books where name like '%/_%' escape '/';

        ID NAME            PRICE
---------- ---------- ----------
         2 Java_1             38
         3 Java_2             40