sql语句基础学习.docx
《sql语句基础学习.docx》由会员分享,可在线阅读,更多相关《sql语句基础学习.docx(20页珍藏版)》请在冰豆网上搜索。
sql语句基础学习
sqlselect语句详解
SELECT[ALL|DISTINCT[ON(expression[,...])]]
*|expression[ASoutput_name][,...]
[FROMfrom_item[,...]]
[WHEREcondition]
[GROUPBYexpression[,...]]
[HAVINGcondition[,...]]
[{UNION|INTERSECT|EXCEPT}[ALL]select]
[ORDERBYexpression[ASC|DESC|USINGoperator][,...]]
[FORUPDATE[OFtablename[,...]]]
[LIMIT{count|ALL}]
[OFFSETstart]
这里from_item可以是:
[ONLY]table_name[*]
[[AS]alias[(column_alias_list)]]
|
(select)
[AS]alias[(column_alias_list)]
|
from_item[NATURAL]join_typefrom_item
[ONjoin_condition|USING(join_column_list)]
输入
expression
表的列/字段名或一个表达式.
output_name
使用AS子句为一个列/字段或一个表达式声明另一个名称.这个名称主要用于标记输出列用于显示。
它可以在ORDERBY和GROUPBY子句里代表列/字段的值.但是output_name不能用于WHERE或HAVING子句;用表达式代替.
from_item
一个表引用,子查询,或者JOIN子句.详见下文.
condition
一个布尔表达式,给出真或假的结果.参见下面描述的WHERE和HAVING子句.
select
一个选择语句,可以有除ORDERBY,FORUPDATE,和LIMIT子句以外的所有特性(甚至在加了括弧的情况下那些语句也可以用).
FROM项可以包括:
table_name
一个现存的表或视图的名字.如果声明了ONLY,则只扫描该表.如果没有声明ONLY,该表和所有其派生表(如果有的话)都被扫描.可以在表名后面跟一个*来表示扫所有其后代表,但在目前的版本里,这是缺省特性.(在PostgreSQL7.1以前的版本里,ONLY是缺省特性.)
alias
用于于前面的table_name.的替换名字,用于缩写或消除一个表自连接时的含混.(此时同一个表要扫描好几次.)如果写了别名,那么你也可以写一个字段别名列表,为表的一个或者几个字段提供替换名字.
select
一个在FORM子句里出现的子查询.它的输出作用好象是为这条SELECT命令在其生存期里创建一个临时表.请注意这个子查询必须用园括弧包围.并且必须给它加别名.
join_type
[INNER]JOIN,LEFT[OUTER]JOIN,RIGHT[OUTER]JOIN,FULL[OUTER]JOIN,或CROSSJOIN.之一.就INNER和OUTER连接类型,必须出现NATURALONjoin_condition,或USING(join_column_list)之一.对于CROSSJOIN,上面的项都不能出现.
join_condition
一个条件限制.类似WHERE条件,只不过它只应用于在这条JOIN子句里连接的两个from_item.
join_column_list
一个USING字段列表(a,b,...)是ON条件left_table.a=right_table.aANDleft_table.b=right_table.b...的缩写.
输出
Rows
你声明的查询返回的所有结果集的行.
count
查询返回的行的计数.
描述
SELECT将从一个或更多表中返回记录行。
选择的侯选行是满足WHERE条件的所有行。
或者如果省略了WHERE语句则选择表中的所有行.(参阅WHERE子句).
实际上,返回的行并不是由FROM/WHERE/GROUPBY/HAVING子句直接生成的行;其实,输出行是通过给每个选出的行计算SELECT输出表达式形成的.你可以在输出列表上写一个*表示选出的行的所有列.同样我们可以拿table_name.*表示来自该表的所以行.
DISTINCT将从选择出来的结果集中删除所有的重复的行。
ALL(缺省)将返回所有侯选行,包括重复的行。
DISTINCTON删除匹配所有你声明的表达式的行,只保留每个重复集的第一行。
DISTINCTON表达式是用和ORDERBY项一样的规则来解释的,见下文.注意这里每个重复集的"第一行"是不可预料的,除非我们用ORDERBY来保证我们希望的行最先出现。
例如,
SELECTDISTINCTON(location)location,time,report
FROMweatherReports
ORDERBYlocation,timeDESC;
检索出每个地区的最近的天气预报。
但是如果我们没有使用ORDERBY来强制每个地区按时间值降续排列,我们得到的将是每个地区的不可预料的时间的报告。
GROUPBY子句允许用户把表分成匹配一个或多个数值的不同行的组.(参考GROUPBY子句.)
HAVING允许只选择那些满足声明条件的行组(参阅HAVING子句.)
ORDERBY导致返回的行按照声明的顺序排列.如果没有给出ORDERBY,输出的行的顺序将以系统认为开销最小的顺序产生.(参阅ORDERBY子句.)
多个SELECT查询可以用UNION,INTERSECT,和EXCEPT操作符组合起来.必要时请使用圆括弧确定这些操作符的顺序.
UNION操作符计算是那些参与的查询所返回的行的集合。
如果没有声明ALL,那么重复行被删除.(参阅UNION子句.)
INTERSECT给出两个查询公共的行。
如果没有声明ALL,那么重复行被删除.(参阅INTERSECT子句.)
EXCEPT给出存在于第一个查询而不存在于第二个查询的行。
如果没有声明ALL,那么重复行被删除.(参阅EXCEPT子句.)
FORUPDATE子句允许SELECT语句对选出的行执行排他锁。
LIMIT子句允许给用户返回一个查询生成的结果的子集。
(参阅LIMIT子句.)
你必须有SELECT权限用来从表中读取数值(参阅GRANT/REVOKE语句.)
FROM子句
FROM子句为SELECT声明一个或多个源表.如果声明了多个源表,则概念上结果是所有源表所有行的迪卡尔积---不过通常会增加限制条件以把返回的行限制为迪卡尔积的一个小子集.
如果FROM项是一个简单表名字,它隐含包括来自该表子表(继承子表)的行.ONLY将消除从该表的子表来的行.在PostgreSQL7.1以前,这是缺省结果,而获取子表的行是通过在表名后面附加*实现的.这种老式性质可以通过命令SETSQL_InheritanceTOOFF;获取.
FROM项也可以是一个加了圆括弧的子查询(请注意子查询需要一个别名子句!
).这个特性非常实用,因为这是在一条查询中获得多层分组,聚集,或者排序的唯一方法.
最后,FROM项可以是一条JOIN子句,它把两个简单的FROM项组合在一起.(必要时使用圆括弧来描述嵌套顺序.)
CROSSJOIN或INNERJOIN是简单的迪卡尔积,和你在顶层FROM里列出这两个项得到的一样.CROSSJOIN等效于INNERJOINON(TRUE),也就是说,不会有任何行被条件删除.这些连接类型只是符号上的便利,因为它们做得一点不比你只利用FROM和WHERE来的多.
LEFTOUTERJOIN返回所有符合条件的迪卡尔积(也就是说,所有符合它的ON条件的组合了的行),另外加上所有没有右手边行符合ON条件的左手边表中的行.这样的左手边行通过向右手边行插入NULL扩展为全长.请注意,当判断哪些行合格的时候,只考虑JOIN自己的ON或USING.然后才考虑外层的ON或WHERE条件.
相反,RIGHTOUTERJOIN返回所有连接的行,另外加上所有未匹配右手边行(左手边插入NULL扩展为全长).这个字句只是符号方便,因为你可以调换左右输入而改用LEFTOUTERJOIN.
FULLOUTERJOIN返回所有连接行,加上所有未匹配的左手边行(右边插入NULL扩展为全长),再加上所有未匹配的右手边行(左手边插入NULL扩展为全长).
除了CROSSJOIN以外的所有JOIN类型,你必须写ONjoin_condition,USING(join_column_list),和NATURAL中的一个.大多数情况下会是ON:
你可以写涉及两个连接表的任何条件表达式.USING字段列表(a,b,...)是ON条件left_table.a=right_table.aANDleft_table.b=right_table.b...的缩写.另外,USING假设两对等式中只有一个包含在JOIN输出中,而不是两个.NATURAL是提及表中所有相似名字字段的USING列表的缩写.
WHERE子句
可选的WHERE条件有如下常见的形式:
WHEREboolean_expr
boolean_expr可以包含任意个得出布尔值的表达式。
通常表达式会是
exprcond_opexpr
或
log_opexpr
这里cond_op可以是:
=,<,<=,>,>=或<>,或条件操作符象ALL,ANY,IN,LIKE等,或者用户定义的操作符,而log_op可以为:
AND,OR,NOT.SELECT将忽略所有WHERE条件不为TRUE的行.
GROUPBY子句
GROUPBY声明一个分了组的表,该表源于应用使用下面的子句:
GROUPBYexpression[,...]
GROUPBY将把所有在组合了的列上共享同样的值的行压缩成一行。
如果存在聚集函数,这些聚集函数将计算每个组的所有行,并且为每个组计算一个独立的值(如果没有GROUPBY,聚集函数对选出的所有行计算出一个数值)。
存在GROUPBY时,除了在聚集函数里面,SELECT输出表达式对任何非组合列的引用都是非法的,因为对一个非组合列会有多于一个可能的返回值。
一个在GROUPBY里面的条目还可以是输出列的名称或者序号(SELECT表达式),或者是一个从输入列的数值形成的任意表达式.当存在语义模糊时,一个GROUPBY名称将被解释成一个输入列/字段名称而不是一个输出列/字段名称.
HAVING子句
可选的HAVING条件有如下形式:
HAVINGboolean_expr
这里boolean_expr和为WHERE子句里声明的相同.
HAVING子句声明一个从前面的子句的结果集中去除了一些不符合boolean_expr.组后分组的表.HAVING与WHERE不同:
WHERE在应用GROUPBY之前过滤出单独的行,而HAVING过滤由GROUPBY创建的行.
在boolean_expr里引用的每个列/字段应该清晰地指明一个组的列/字段,除非引用在一个聚集函数里。
ORDERBY子句
ORDERBYexpression[ASC|DESC|USINGoperator][,...]
一个ORDERBY项可以是一个输出列(SELECT表达式)的名字或者序数,或者它也可以是任何来自输入列值形成的表达式.在出现混淆的场合下,ORDERBY名字将被解释成一个输出名字.
序数指的是列/字段按顺序(从左到右)的位置.这个特性可以使得对没有一个合适名称的列/字段的排序成为可能.这一点可能永远没有用,因为总是可以通过AS子句给一个要计算的列/字段赋予一个名称,例如:
SELECTtitle,date_prod+1ASnewlenFROMfilmsORDERBYnewlen;
还可以ORDERBY任意表达式(一个对SQL92的扩展),包括那些没有出现在SELECT结果列表里面的域。
因此下面的语句现在是合法的:
SELECTnameFROMdistributorsORDERBYcode;
这个特性的一个局限就是应用于UNION,INTERSECT,或者EXCEPT查询的ORDERBY子句只能在一个输出字段名或者数字上声明,而不能在一个表达式上声明.
请注意如果一个ORDERBY条目是一个匹配结果列和输入列的简单名称,ORDERBY将把它解释成结果列名称.这和GROUPBY在同样情况下做的选择正相反.这样的不一致是由SQL92标准强制的.
我们可以给ORDERBY子句里每个列/字段加一个关键字DESC(降序)或ASC(升序).如果不声明,ASC是缺省.我们还可以声明一个排序操作符来实现排序。
ASC等效于使用'<'而DESC等效于使用'>'。
在一个域里,空值排序时排在其它数值前面.换句话说,升序排序时,空值排在末尾,而降序排序时空值排在开头.
UNION子句
table_queryUNION[ALL]table_query
[ORDERBYexpression[ASC|DESC|USINGoperator][,...]]
[LIMIT{count|ALL}[{OFFSET|,}start]]
这里table_query表明任何没有ORDERBY,FORUPDATE,或者LIMIT子句的选择表达式.(如果用圆括弧包围,ORDERBY和LIMIT可以放在子表达式里.如果没有圆括弧,这些子句将交给UNION的结果使用,而不是给它们右手边的输入表达式.)
UNION操作符的结果集是那些涉及到的所有查询所返回结果的集合。
两个做为UNION直接操作数的SELECT必须生成相同数目的字段,并且对应的字段必须有兼容的数据类型。
缺省地,UNION的结果不包含任何重复的行,除非声明了ALL子句.ALL制止了消除重复的动作.
同一SELECT语句中的多个UNION操作符是从左向右计算的,除非用圆括弧进行了标识).
目前,FORUPDATE不能在UNION的结果或输入中声明.
INTERSECT子句
table_queryINTERSECT[ALL]table_query
[ORDERBYexpression[ASC|DESC|USINGoperator][,...]]
[LIMIT{count|ALL}]
[OFFSETstart]
这里table_query声明任何没有ORDERBY,FORUPDATE,或者LIMIT子句的选择表达式。
INTERSECT类似UNION,只不过它给出在两个查询中都出现的行,而不是两个查询的所有行.
INTERSECT的结果不包含任何重复行,除非你声明了ALL选项.用了ALL以后,一个在L里有m个重复而在R里有n个重复的行将出现min(m,n)次.
除非用圆括号指明顺序,同一SELECT语句中的多个INTERSECT操作符是从左向右计算的。
INTERSECT比UNION绑定得更紧---也就是说AUNIONBINTERSECTC将读做AUNION(BINTERSECTC),除非你用圆括弧声明.
EXCEPT子句
table_queryEXCEPT[ALL]table_query
[ORDERBYexpression[ASC|DESC|USINGoperator][,...]]
[LIMIT{count|ALL}]
[OFFSETstart]
这里table_query声明任何没有ORDERBY,FORUPDATE,或者LIMIT子句的选择表达式。
EXCEPT类似于UNION,只不过EXCEPT给出存在于左边查询输出而不存在于右边查询输出的行。
EXCEPT的结果不包含任何重复的行,除非声明了ALL选项.使用ALL时,一个在L中有m个重复而在R中有n个重复的行将出现max(m-n,0)次.
除非用圆括弧指明顺序,同一SELECT语句中的多个EXCEPT操作符是从左向右计算的。
EXCEPT和UNION绑定级别相同.
LIMIT子句
LIMIT{count|ALL}
OFFSETstart
这里count声明返回的最大行数,而start声明开始返回行之前忽略的行数。
LIMIT允许你检索由查询其他部分生成的行的某一部分。
如果给出了限制计数,那么返回的行数不会超过哪个限制。
如果给出了一个偏移量,那么开始返回行之前会忽略那个数量的行。
在使用LIMIT时,一个好习惯是使用一个ORDERBY子句把结果行限制成一个唯一的顺序。
否则你会得到无法预料的查询返回的子集---你可能想要第十行到第二十行,但以什么顺序?
除非你声明ORDERBY,否则你不知道什么顺序。
从PostgreSQL7.0开始,查询优化器在生成查询规划时把LIMIT考虑进去了,所以你很有可能因给出的LIMIT和OFFSET值不同而得到不同的规划(生成不同的行序)。
因此用不同的LIMIT/OFFSET值选择不同的查询结果的子集将不会产生一致的结果,除非你用ORDERBY强制生成一个可预计的结果顺序。
这可不是毛病;这是SQL生来的特点,因为除非用了ORDERBYE约束顺序,SQL不保证查询生成的结果有任何特定的顺序。
用法
将表films和表distributors连接在一起:
SELECTf.title,f.did,d.name,f.date_prod,f.kind
FROMdistributorsd,filmsf
WHEREf.did=d.did
title |did| name |date_prod |kind
---------------------------+-----+------------------+------------+----------
TheThirdMan |101|BritishLion |1949-12-23|Drama
TheAfricanQueen |101|BritishLion |1951-08-11|Romantic
UneFemmeestuneFemme |102|JeanLucGodard |1961-03-12|Romantic
Vertigo |103|Paramount |1958-11-14|Action
Becket |103|Paramount |1964-02-03|Drama
48Hrs |103|Paramount |1982-10-22|Action
WarandPeace |104|Mosfilm |1967-02-12|Drama
WestSideStory |105|UnitedArtists |1961-01-03|Musical
Bananas |105|UnitedArtists |1971-07-13|Comedy
Yojimbo |106|Toho |1961-06-16|Drama
There'saGirlinmySoup|107|Columbia |1970-06-11|Comedy
TaxiDriver |107|Columbia |1975-05-15|Action
AbsenceofMalice |107|Columbia |1981-11-15|Action
Storiadiunadonna |108|Westward |1970-08-15|Romantic
TheKingandI |109|20thCenturyFox|1956-08-11|Musical
DasBoot |110|BavariaAtelier |1981-11-11|Drama
BedKnobsandBroomsticks|11