SQL学习之用通配符进行数据过滤
一、Like操作符
之前介绍的所有的操作符都是针对已知值进行过滤。不管匹配一个值还是多个值,检验大于还是小于已知值,或者检查某个范围的值,其共同点是过滤中使用的值都是已知的。
但是这种方法并不是任何时候都好用。有如下代码:
select ItemId,ItemName,CheckValueNum,CheckValueString,ResultLevel from T_Check_InfoDetail
需求:现在需要检索ItemName中包含"心率"的行记录,这个时候使用简单的比较操作符肯定不行,必须使用通配符。利用通配符,可以 创建 比较 特定的数据 的搜索模式,在这里如果我们想找出ItemName包含"心率"的行记录,可以构造一个通配符搜索模式:
通配符:用来匹配值的一部分的特殊字符。
搜索模式:由字面值、通配符或两者组合构成的搜索条件。
而使用通配符搜索模式,必须使用LIKE操作符,LIKE指示DBMS(数据库管理系统),后跟的搜索模式利用通配符匹配而不是简单的相等匹配进行比较。
这里上面提出的检索要求我们还没有完成,在下面介绍完通配符后再完成上面的检索任务。
二、通配符
1、百分号(%)通配符
这个通配符使我们日常开发中最常使用的通配符,在搜索串中,%表示任何字符出现任意次数(包括0次),现在我通过"%"通配符来完成上面提出的需求代码如下:
select ItemId,ItemName,CheckValueNum,CheckValueString,ResultLevel from T_Check_InfoDetail where ItemName LIKE '心率%'
ok,完成了上面的需求。
这段代码使用了搜索模式'心率%',在执行这条子句时,将检索任意ItemName列值以'心率'开头的词。%告诉DBMS(数据库管理系统)接收'心率'之后的任意字符,不管他有多少字符。
下面我们盖面上面的需求,检索ItemName列值中包含'范围'的行数据,这个时候用上面'范围%'的搜索模式就无法搜索出来,下面是解决代码:
select ItemId,ItemName,CheckValueNum,CheckValueString,ResultLevel from T_Check_InfoDetail where ItemName LIKE '%范围%'
搜索模式'%范围%'表示匹配任何位置上包含文本'范围'的值,不论他之前或之后出现什么字符。
这里表示搜索ItemName列值中包含'范围'的行数据,不论它之前或者之后出现什么字符。
下面再次更改上面的需求,检索ItemName列值中以'心'开头,以'定'结尾的行数据。下面是解决代码:
select ItemId,ItemName,CheckValueNum,CheckValueString,ResultLevel from T_Check_InfoDetail where ItemName LIKE '心%定'
这段代码使用了搜索模式'心%定',在执行这条子句时,将检索任意ItemName 列值以'心'开头,已'定'结尾的行数据,%告诉DBMS(数据库管理系统)接收'心'之后,'定'之前的任意字符,不管这中间有多少字符。
在使用'%'匹配的时候,需要注意的几点:
1、%几乎可以匹配任何东西,但有个例外,这就是null。
2、注意搜索模式'心%定 ',发现定后面有一个空格,而这个空格恰好改变了我们的检索的初衷,这时候DBMS回去匹配以'定 '结尾的行数据,所以在使用通配符匹配数据的时候,一定要注意空格。
2、下划线( _ )通配符
下划线(_)通配符与百分号通配符的作用一样,但他只匹配单个字符,而不是多个字符。如下代码:
select * from dbo.course where tno='t003'
现在我们需要检索cname列值中SERVER 2005前面带一个空格再加上三个字符的行数据,下面是解决代码:
select * from dbo.course where cname like '___ SERVER 2005'
ok,完成需求.这里一共三个下划线,刚好匹配了三个字符,一个不多一个不少,且这三个字符位于cname列值的开头.如果前面还有字符,像 SQL SERVER 2005,前面还有一个空格,这样的数据就无法匹配到!
注意:这里的空格问题,不能多也不能少!
3、方括号([])通配符
方括号( [] )用来指定一个字符集,他必须匹配指定位置(通配符的位置)的一个字符(也就是说必须指定通配符的位置,也就是需要检索的字符的位置)。代码如下:
select * from dbo.student
现在我们需要检索出sname列值中以'张'或'王'开头的学生,下面是解决代码:
select * from dbo.student where sname like '[张王]%'
select * from dbo.student where sname like '%[张王]%'
这个搜索模式使用了两个不同的通配符,[张王]匹配方括号中的任意一个字符,他也只能匹配单个字符,任何多于一个字符的名字(也就是说你想用[]通配符检索sname列值为'李波'的是无法匹配的)都不匹配,%通配符匹配单个字符之后的任意数字的字符(包括0个)。
现在我们变下需求,我们需要检索sname列值中除了姓张和姓王之外的所有学生的姓名,和上面的需求刚好相反,下面是解决代码:
第一种方法:使用not操作符
select * from dbo.student where sname not like '[张王]%'
第二种方法:使用^前缀
select * from dbo.student where sname like '[^张王]%'
结果都是一样!
通配符虽然好用,但是我们使用这种功能也是有代价的!
(1)通配符搜索比其他的操作府搜索耗费的时间更长!
(2)在确实需要使用通配符时,尽量不要把他们用在搜索模式的开始,因为把他至于搜索模式的开始,搜索起来是很慢的!
(3)注意通配符的位置,如果放错地方,可能不会返回想要的数据!