Fighting Ant

Ant can be great while elephant can be chickenshit

导航

复杂查询

Posted on 2008-07-02 17:32  Nillson  阅读(393)  评论(0编辑  收藏  举报

 

select col1, col2 from dbName.tbName where colName=value
上面这个是再简单不过的查询了,如果不加上别的猫腻儿,数据库的查询实在是太简单了,但是事实不会如此,因为问题本就不那么简单,所以查询语句也就复杂了。
几个关键字:
Null
排序
比较运算符
逻辑运算符
IN
运算符
Like
模糊查询
Null
Null是一个特殊的值, Null与其它任何值都不相等,包括bool类型的false。对Null取反的结果还是Null.
运行下面这段查询代码,可以得到如下结果

create table NullTest
(
TName 
char(30not null,
Salary 
int
)
insert into NullTest values('Nillson'1000)
insert into NullTest values('Jack'null)
insert into NullTest values('Rose'500)
insert into NullTest values('Perter'1100)
select * from NullTest where salary >= 1000
select * from NullTest where salary < 1000
drop table NullTest


TName Salary
Nillson  1000
Perter   1100
**************
TName Salary
Rose    500
可以看出Jack的即不在大于等于1000之内,也不在小于1000之内。

排序
Where 子句后用Order by 可以对查询结果进行排序,排序的顺序分为顺序排序和逆序排序。默认情况下是按照升序排序,如果制定了DESC关键字则按照逆序排序。排序可以对单列和多列排序。当采用多列排序时,各列排序的优先级根据Order by子句后指定的列的位置不同而不同,越靠前被指定,该列的优先级越高。

比较运算符
比较运算符包括: =, >, <, <>, >=, <=, !=, Between等等,在此不罗嗦了
逻辑运算符
逻辑运算符有AND, OR, NOT,IN
在此需要注意的一点是AND 的优先级要比OR高,如果我们需要用AND 连接两个OR必须要把OR打上括号。
IN
OR的关系,IN在大多数情况下可以改写成OR,例如:
select * from salary where name in ('Empolyee1', 'Empolyee2'.....)
可以改写成select * from salary where name='Employee1' or name='Employee2'...
但是IN后面的括号内可以跟一个select语句,这就是说它允许把一个查询语句的查询结果作为另一个查询语句的查询范围限制,这一点是OR所无法做到的。
:select * from salary where name in (select name from Departmentone).

Like模糊查询
模糊查询需要注意的是几个通配符的用法:%, _, []ESCAPE
"%"
代表任意多个字符例如'%Computer'代表以Computer结尾的任意字符,而'Computer%'则表示以Computer开头任意长字符。当然'%Computer%更狠,所有包含Computer的字符。
"-"
代表任意一个字符(书上是这么说的,但是偶认为这种说法是不对的,"-"应该代表0个或1个任意字符。例如执行如下语句会得到这样的结果

drop table regtest
create table regtest
(
TName 
char(30)
)
insert into regtest values('computer')
insert into regtest values('computerA')
insert into regtest values('computerAB')
select * from regtest where TName like 'computer__' 


TName
computer
computerA
computerAB
而我的本意是要查找computer后面跟两个字符的,所以查询语句要改成这样

select * from regtest where TName like 'computer__' and TName not like 'computer_'


这样的结果就OK
TName
computerAB
"[]"
用于指定一些烈的字符,只要满足这些字符中的一个,且位置在"[]"通配符那里就能满足查询条件,我觉得这里说的也不严密,应该是有且仅有一个字符。例如执行如下查询

create table regtest
(
TName 
char(30)
)
insert into regtest values('hpllo')
insert into regtest values('hello')
insert into regtest values('haello')
insert into regtest values('hallo')
insert into regtest values('h%llo')
select * from regtest where TName like 'h[abcde%]llo'


查询结果为
TName
hello
hallo
h%llo
这里有两点需要说明:第一, 'haello'与通配符"[]"内的两个字符都匹配,但是结果中并没有haello说明只取了通配符"[]"内的一个字符。
第二, "%"在一般的情况下是作为通配符的,但是在"[]"内就变为一般的字符了。所以'h%llo'被查询到但是'hpllo'则不符合查询条件。
"[]"内列出的字符前加符号"^"就表示否定的意思。例如 Like '[^abc]'就表示在[]的位置上不能有abc中的任何一个。
"ESCAPE"
的作用在于指定一个转义字符。这个东东跟C# 中的转义字符作用一样,但是使用起来更灵活,但是俺感觉这么一灵活反倒麻烦起来了。
例如下面的语句

Like '%M%' escape 'M'

在这里ESCAPE定义了一个转义字符MM后的'%'被认为是普通字符而非通配符。
还有一点需要注意:这条语句在于查找以字符%结尾的任意字符串,不管其中是否含有字符M.也就是说一旦某个字符被定义为转义字符之后,它将失去它原来的意义。只起标记其后的一个字符的作用。起作用想当于C#里的"\"而非"@"例如执行下面这段代码

create table regtest
(
TName 
char(30)
)

insert into regtest values('ppk%')
insert into regtest values('jason%[]')

select * from regtest where TName like '%q%q[q]' escape 'q'
select * from regtest where TName like '%q%[]' escape 'q'

我们的本意是要查找以%[]结尾的字符串,第一个select语句可以得到正确的结果,然而第二条语句无法得到我们想要的结果。事实上最后一位在通配符"[]"内没有制定任何字符,所以无论数据库中的字符串以什么结尾都不可能符合条件。
一个小问题:'[^]'等同于'_'?
答案: Yes
我怀疑数据库把空字符也当成一种字符,'[^]'相当于否定了"nothing"那么也就是肯定了"everything"当然也就包括空字符了。这与'_'的定义刚好吻合。
注意空值与Null并没有什么关系。甚至Null本身也与它不等
例如执行如下的代码:
create table regtest
(
TName 
char(30)
)
insert into regtest values(null)
select * from regtest
select * from regtest where TName = Null

第二个查询语句得到了什么?Nothing!!!