查询命令的完整语法:
一.一般语句:
Select [all| distinct ] select-list
[ from tableView-list ]
[where search-condition ]
[ group by column-name, ... ]
[ having search-condition ]
[ order by { expression | integer } [ ASC |DESC ], ... ]
说明:
[]表示可选可不选项,{}表示多选一,| 表示或;
select-list: expression[ [ AS ] alias-name ] | *
from:联结查询:连接查询是指查询的数据涉及两个以上的表。
实现要点:from子句中包括涉及的表名列表,连接的条件在where子句中给出。若在form子句中没有连接类型,又不给出where子句,则形成广义笛卡儿积;指定where子句可以形成θ连接和自然连接。
where:条件查询:使用WHERE子句,可以选择表中指定的行。WHERE子句后面的查询条件(search-condition)是一个结果为逻辑型值的表达式。命令返回使得查询条件为真的所有行。
search condition的形式:
expression θ expression
expression IS [ NOT ] NULL
expression [ NOT ] LIKE expression [ESCAPE expression]
expression [ NOT ] BETWEEN expression AND expression
expression [ NOT ] IN (value-expr1 , value-expr2 [, value-expr3 ] ... )
NOT condition | condition AND condition | condition OR condition
condition IS [ NOT ] UNKNOWN
模糊查询:查询条件中涉及的字符型数据的值不确切。
要点:使用like谓词和通配符“_”,“%”,[ ],[^]。下划线和单个字符匹配,百分号和任意长度的字符串(包括0个)匹配。[ ]和括号内的字符匹配,[^ ]不和括号内的字符匹配。
group by:对查询结果分组:对查询结果分组的方法是使用group by子句,group by后面跟按其值进行分组的列名(或列名序列)。
having:对分组的查询结果再进行选择;
order by:对查询结果排序, 默认为asc(升序);
指定在 DELETE、SELECT 和 UPDATE 语句中使用的表、视图、派生表和连接表的
语法:
[ FROM { < table_source
<table_source
table_name [ [ AS ] table_alias ] [ WITH ( <table_hint > [ ,...n ] ) ]
| view_name [ [ AS ] table_alias ] [ WITH ( < view_hint> [ ,...n ] ) ]
| rowset_function [ [ AS] table_alias ]
| user_defined_function[ [ AS ] table_alias ]
|derived_table [ AS ] table_alias [ ( column_alias [ ,...n ] ) ]
joined_table
< joined_table> ::=
join_type
| < table_source > CROSS JOIN < table_source >
| [ ( ]< joined_table > [ ) ]
<join_type > ::=
[ INNER | { { LEFT | RIGHT |FULL } [OUTER] } ]
[ < join_hint > ]
JOIN
说明:
[]表示可选可不选项,{}表示多选一,| 表示或;
外连接分为左外连接和右外连接。
左外连接
A LEFT OUTER JOIN B
不管左面表(A)中的元组满足不满足连接条件,都将出现在结果集中。如果A中的某个元组在右表(B)中没有对应的元组,则结果集中相应于B的元组分量取空值(NULL),
右外连接
A RIGHT OUTER JOIN B
右外连接与左外连接正好相反。
例子可参考下一篇关于BD的博文,关于DB作业的语句查询。
二.聚集函数(Aggregate function):
AVG ( aggregate-parm ) //求均值
COUNT ( * ) //求记录数
COUNT ( aggregate-parm ) //求记录数/
LIST ( aggregate-parm ) //返回字符串列表(字符串间用逗号分隔,SQLServer不支持)
MAX ( aggregate-parm ) //求最大值
MIN ( aggregate-parm ) //求最小值
SUM ( aggregate-parm ) //求和
说明:
聚集函数的参数(aggregate-parm)的形式如下:
DISTINCT column-name | expression
三.嵌套查询(子查询):
嵌套查询:在一个查询的where子句中包含另一个查询。 要点:在where子句中嵌入子查询。一般要使用谓词in,not in,exists,notexists,all,any
IN谓词:
表达形式:expression IN (subquery) | expressionIN (val{,val…})
非相关子查询:子查询没有接受任何输入数据的情况下向外层的SELECT语句传递一个行集,即内层的子查询完全独立于外层的SELECT语句。执行顺序是:先执行内层子查询,然后执行外层。
相关子查询:一个要使用外层SELECT语句所提供的数据的子查询。执行过程是:假定内层子查询使用外层SELECT语句的变量X,则对于X的每一个取值,都执行一次内层子查询。
注意:所有使用IN谓词的嵌套子查询都能被转化成多表连接查询(FROM子句中有多个表)
Eg1:查询选修了课程‚C1”的学生的学号(S#)和姓名(SN):
非相关子查询:
Select S#,SN
from S
where S# IN(
Select S#
from SC
where C#=‘C1’)
相关子查询:
Selectdistinct S#,SN
from S
where ‘C1’ IN(
select C#
from SC
where S.S#= SC.S# )
NOT IN谓词:
表达形式:expression NOT IN (subquery) | expressionNOT IN (val{,val…})
EXISTS 谓词:
表达形式为: EXISTS(Subquery)
谓词EXISTS(Subquery)为真当且仅当子查询返回一个非空的集合;
NOT EXISTS 谓词:
表达形式为:[NOT]EXISTS(Subquery)
谓词NOTEXISTS(Subquery)为真当且仅当子查询返回的集合为空;
NOTEXISTS带来新的功能:一些带EXISTS的子查询不能被其它形式的子查询等价替换,但所有带IN、比较运算符、ANY和ALL谓词的子查询都能用带EXISTS的子查询等价替换,用NOTEXISTS谓词实现关系代数的差运算。
Eg2:查询所有选修了‘C1’号课程的学生的姓名。
Select SN
from S
whereexists (
select*
from SC
where S#=S.S# andC#="C1")
Eg3:查询没有选修‘C1’号课程的学生的姓名。
Select SN
from S
wherenotexists (
select*
from SC
where S#=S.S# andC#="C1")
量化比较谓词 :
定义:
对于θ,两个等价的谓词expressionθSOME(Subquery)和expressionθANY(Subquery)为真,当且仅当至少存在一个由子查询返回的元素s,expressionθs为真;
对于θ,expressionθALL(Subquery)为真,当且仅当对每一个由子查询返回的元素s,expressionθs为真;
表达形式:
expression {SOME|ANY|ALL}(Subquery)
说明:
[]表示可选可不选项,{}表示多选一,| 表示或;
ε{<,<=,=,<>,>,>=}
该形式中的SOME与ANY含义相同(尽SOME与ANY含义相同,但多用SOME而不用ANY)
Eg4:查询与‘刘晨’在同一个系学习的学生。
Select S#,SN,SD
from S
where SD =(
select SD
from S
where SN="刘晨")
Eg5:查询其它系中比信息系某一学生年龄小的学生姓名和年龄
Select SN,SA
from S
where SA< SOME (
select SA
from S
where SD="IS" )
and SD <>"IS"
Eg6:查询其它系比信息系所有学生年龄小的学生的姓名和年龄
Select SN,SA
from S
where SA < ALL (
select SA
from S
where SD="IS")
AND SD <>"IS"
UNION 运算:
UNION运算实现关系代数的‚”并”运算
表达形式:
SubqueryUNION[ALL]Subquery
ALL:对于两个子查询中的公共行,UNION结果将包含两个相同的行
带量词的查询:
量词查询:查询条件中涉及到量词 “存在”,“全称”。
要点:SQL中“存在”量词用 EXISTS,“不存在”使用 NOT EXISTS。没有“全称”量词,但全称量词可以用“存在”量词来实现。 " 全部x满足条件p " 可以表达为 "不存在x不满足条件p"
Eg7:“查询选修全部课程的学生姓名”
(∨x)P≡!(Ex(!P)),原命题等价于:“查询这样的学生a,不存在某个课程x,这名学生没有选修”
Select SN
from S
where notexists (
select*
from C
wherenotexists (
select *
from SC
where S#=S.S#
and C#=C.C#)
)
Eg8:查询至少选修了学生‘95002’选修的全部课程的学生号码
语义转换:查询学号为x的学生,对所有的课程y,只要95002选修了课程y,则x也选修了y。
形式化:p----学生95002选修了课程y;q----学生x选修了课程y;
则上述查询为:(y)p→q
谓词演算转换:
(y)p→q¬( y(¬(p→q)))¬( y(¬(¬P∨q)))
¬(y(P∧¬q)))
表达的语义:查询学号为x的学生,不存在这样的课程y,学生95002选修了y,而学生x没有选。
Select S#
from S
wherenotexists(
select*
from C
wherenotexists(
select*
from SC,SCX
whereSCX.C#=C.C# andSCX.S#="95002")
andnotexists(
select*
from SC,SCY
whereSCY.C#=C.C# andSCY.S#=S.S# )
或者:
Selectdistinct S#
from SCSCX
wherenotexists(
select*
from SC,SCY
whereSCY.S#="95002"
andnotexists(
select*
from
where SCZ.S#=SCX.S#
andSCZ.C#=SCY.C#))
四.关于临时表:
有两种临时表,一种是永久性的临时表,该种表用create命令建立,语法为create global temporary table table_name...,一种是用select 命令建立,语法如上例。这两种临时表的区别是:
1.表名的区别
2.永久性的临时表要用drop table命令删除,而#临时表在DISCONNECT后自动被删除。
3.缺省时,永久性的临时表中的记录在一次事物处理之后(COMMIT或ROLLBACK)或连接终止后被自动清除(也可以设置为保留),而#临时表不会。
4.永久性的临时表可以同时拥有多个连接(connection),但每个连接仅能看到自己插入的记录。而#临时表仅在一次连接中有效。