学SQL(WHERE(2)、NOT、IN、通配符、正则表达式)

WHERE(2)——使用AND,OR,IN,NOT

使用AND

--检索由供应商1003制造的,价格在在10以下的所有产品的名称和价格
select prod_id,prod_price,prod_name
from products
where vend_id = 1003 and prod_price <= 10; 

使用OR

--检索由两个供应商之一制造的任何产品和价格
select prod_name,prod_price
from products
where vend_id = 1002 or vend_id = 1003;

求值顺序:AND > OR

--检索供应商为1002的所有产品,供应商为1003且价格超过10的产品
select prod_name,prod_price
from products
where vend_id = 1002 or vend_id = 1003 and prod_price >=10;
--检索供应商为1002或1003,且产品价格超过10的产品
select prod_name,prod_price
from products
where (vend_id = 1002 or vend_id = 1003) and prod_price >=10;

使用IN

select prod_name,prod_price
from products
where vend_id in (1002,1003)/*括号内:有效值列表*/
order by prod_name;

IN优于OR:

1.求值顺序更容易管理(因为它使用了比OR更少的运算符)。

2.执行更快。

3.IN运算符可以包含一条新的select语句。

使用NOT

select prod_name,prod_price
from products
where vend_id not in (1002,1003)
order by prod_name;

通配符

通配符(Wildcard):用于匹配值的某些部分的特殊字符。

搜索模式(Search Pattern):由字面意义的文本、通配符字符或者二者的任意组合构成的搜索条件。

%:“匹配出现任意次数的任意字符——可以是0次”

select prod_id,prod_name
from products
where prod_name like 'Jet%';
select prod_id,prod_name
from products
where prod_name like '%anvil%';

注意:①大小写敏感;②留心尾部空格(解决:搜索模式末尾加“%”;用函数剪切空格);③留心null(“%”不匹配null值)。

_:“只匹配单个字符——不多也不少”

select prod_name,prod_price
from products
where prod_name like '_ ton anvil%';

注意:①不要过度的使用通配符;②尽量不要在开头使用通配符(速度变慢);③注意通配符的位置。


正则表达式——简易(正则表达式后续单独写一篇~~)

正则表达式是什么?

正则表达式是一种用于匹配文本的特殊语言的一部分。例如:需要从文本中提取电话号码,可能会需要使用一个正则表达式。

Oracle PL/SQL 提供了四种可以访问正则表达式的函数:

regexp_like( ):用于搜索字符。

regexp_replace( ):用于替换字符串中的字符。

regexp_instr( )、regexp_substr( ):在字符串内搜索字串。

示例:

--基本的字符匹配
select prod_name
from products
where regexp_like(prod_name, '1000')
order by prod_name;
/*
对比:
1.
where子句需要给它传递一个列名称,一个值,以及一个运算符(例如=,like)、
regexp_like()是一个接受参数的函数,它会返回TRUE和FALSE,TRUE的话就匹配where子句,并且返回它。
2.
like匹配整个列,如果要匹配的文本位于列值的中间,like将不会找到它。
regexp_like()会在列值中寻找匹配,若要匹配的部分位于列值中间,会找到它并返回行。
*/
--“.”:“匹配任意单个字符”
select prod_name
from products
where regexp_like(prod_name, '.000')
order by prod_name;
--“|”:or匹配
select prod_name
from products
where regexp_like(prod_name, '1000|2000|3000')
order by prod_name;
例子:
select prod_name
from products
where regexp_like(prod_name, '1|2|3 ton')/*将匹配1或2或3 ton*/
--匹配多个字符之一“[]”
select prod_name
from products
where regexp_like(prod_name, '[123] ton')/*将匹配1 ton或2 ton或3 ton*/
order by prod_name;
--“^”:字符集取反[^123]
select prod_name
from products
where regexp_like(prod_name, '[^123] ton')
order by prod_name;
--匹配范围[0-9];[a-z]
select prod_name
from products
where regexp_like(prod_name, '[1-5] ton')
order by prod_name;
--匹配特殊字符:需要在前面加“\”
select vend_name
from vendors
where regexp_like(vend_name, '\.')
order by vend_name;
/*这个过程称为转义(Escape)*/

匹配字符类别

类别 描述
\d 任意数字(等同于[0-9])
\D 任意非数字字符(等同于[^0-9])
\w 任意字母或数字(等同于[a-zA-Z0-9])
\W 任意非字母或数字(等同于[^a-zA-Z0-9])
\s 任意空白字符
\S 任意非空白字符

匹配重复次数

元字符 描述
* 0个或多个匹配
+ 1个或多个匹配(等价于{1,})
? 0个或1个匹配(等价于{0,1})
{n} 具体的匹配次数
{n,} 不少于指定的匹配次数
{n,m} 匹配的范围

示例:

select prod_name
from products
where regexp_like(prod_name, '\(\d sticks?\)')
order by prod_name;
/*
结果:
prod_name
TNT (1 stick)
TNT (5 sticks)
分析: \(:匹配( \d:匹配任意数字 sticks?:匹配stick或sticks
*/ select prod_name from products where regexp_like(prod_name, '\d{4}')/*匹配任意四个连续的数字*/ order by prod_name; /*还可写为:'[0-9]{4}'*/

锚用于匹配特定位置的文本(例如查找以某个数字开头的产品)

锚元字符 描述
^ 文本的开头
$ 文本的末尾
select prod_name
from products
where regexp_like(prod_name, '^[0-9\.]')
order by prod_name;

注:“^”在字符集[]内使用时,表示取反;否则表示指示字符串的开头。使用锚可以使得regexp()像like那样,只需在开头加^,在末尾加$。

 

参考文献:《Oracle PL\SQL 必知必会》[美] Ben Forta 著 傅强 译(第7-9章,64-99页)。

 

posted @ 2018-07-27 20:38  六日  阅读(2940)  评论(0编辑  收藏  举报