【网学网提醒】:网学会员为大家收集整理了SQLselect语法大全提供大家参考,希望对大家有所帮助!
SQLselect语法大全200908140833SQLselect语法大全
httphi.baiduthumb8blogitem92b120d21606573c970a16b6.html
SQL里面最常用的命令是SELECT语句,用于检索数据。先来看一下语法:
SELECT[ALLDISTINCT[ON(expression[,...])]]
*|expression[ASoutput_name][,...]
[INTO[TEMPORARYTEMP][TABLE]new_table]
[FROMfrom_item[,...]]
[WHEREcondition]
[GROUPBYexpression[,...]]
[HAVINGcondition[,...]]
[{UNIONINTERSECTEXCEPT[ALL]}select]
[ORDERBYexpression[ASCDESCUSINGoperator][,...]]
[FORUPDATE[OFclass_name[,...]]]
[LIMIT{countALL}[{OFFSET,}start]]
现在我们将通过不同的例子演示SELECT语句复杂的语法。用于这些例子的表在供应商和部件数据库里定义。
Example1-4.带有条件的简单查询
要从表PART里面把字段PRICE大于10的所有记录找出来,我们写出下面查询:
SELECTFROMPART
WHEREPRICE10;
然后得到表:
PNOPNAMEPRICE
-----+---------+--------
3Bolt15
4Cam25
在SELECT语句里使用将检索出表中的所有属性。如果我们只希望从表PART中检索出属性PNAME和PRICE,我们使用下面的语句:
SELECTPNAME,PRICE
FROMPART
WHEREPRICE10;
这回我们的结果是:
PNAMEPRICE
--------+--------
Bolt15
Cam25
请注意SQL的SELECT语句对应关系演算里面的projection(映射),而不是selection(选择)(参阅关系演算获取详细信息)。
WHERE子句里的条件也可以用关键字OR,AND,和NOT逻辑地连接起来:
SELECTPNAME,PRICE
FROMPART
WHEREPNAME='Bolt'AND
(PRICE=0ORPRICE=15);
这样将生成下面的结果:
PNAMEPRICE
--------+--------
Bolt15
目标列表和WHERE子句里可以使用算术操作。例如,如果我们想知道如果我们买两个部件的话要多少钱,我们可以用下面的查询:
SELECTPNAME,PRICE2ASDOUBLE
FROMPART
WHEREPRICE250;
这样我们得到:
PNAMEDOUBLE
--------+---------
Screw20
Nut16
Bolt30
请注意在关键字AS后面的DOUBLE是第二个列的新名字。这个技巧可以用于目标列表里的每个元素,给它们赋予一个在结果列中显示的新的标题。这个新的标题通常称为别名。这个别名不能在该查询的其他地方使用。
1.4.1.2.Joins(连接)
下面的例子显示了SQL里是如何实现连接的。
要在共同的属性上连接三个表SUPPLIER,PART和SELLS,我们通常使用下面的语句:
SELECTS.SNAME,P.PNAME
FROMSUPPLIERS,PARTP,SELLSSE
WHERES.SNO=SE.SNOAND
P.PNO=SE.PNO;
而我们得到的结果是:
SNAMEPNAME
-------+-------
SmithScrew
SmithNut
JonesCam
AdamsScrew
AdamsBolt
BlakeNut
BlakeBolt
BlakeCam
在FROM子句里,我们为每个关系使用了一个别名,因为在这些关系间有着公共的命名属性(SNO和PNO)。现在我们可以区分不同表的公共命名属性,只需要简单的用每个关系的别名加上个点做前缀就行了。联合是用与一个内部联接里显示的同样的方法计算的。首先算出笛卡儿积SUPPLIER×PART×SELLS。然后选出那些满足WHERE子句里给出的条件的记录(也就是说,公共命名属性的值必须相等)。最后我们映射出除S.SNAME和P.PNAME外的所有属性。
另外一个进行连接的方法是使用下面这样的SQLJOIN语法:
selectsname,pnamefromsupplier
JOINsellsUSING(sno)
JOINpartUSING(pno);
givingagain
snamepname
-------+-------
SmithScrew
AdamsScrew
SmithNut
BlakeNut
AdamsBolt
BlakeBolt
JonesCam
BlakeCam
(8rows)
一个用JOIN语法创建的连接表,是一个出现在FROM子句里的,在任何WHERE,GROUPBY或HAVING子句之前的表引用列表项.其它表引用,包括表名字或者其它JOIN子句,如果用逗号分隔的话,可以包含在FROM子句里.连接生成的表逻辑上和任何其它在FROM子句里列出的表都一样.
SQLJOIN有两种主要类型,CROSSJOIN(无条件连接)和条件连接.条件连接还可以根据声明的连接条件(ON,USING,或NATURAL)和它应用的方式(INNER或OUTER连接)进一步细分.
连接类型
CROSSJOIN
{T1}CROSSJOIN{T2}
一个交叉连接(crossjoin)接收两个分别有N行和M行的表T1和T2,然后返回一个包含交叉乘积NxM条记录的连接表.对于T1的每行R1,T2的每行R2都与R1连接生成连接的表行JR,JR包含所有R1和R2的字段.CROSSJOIN实际上就是一个INNERJOINONTRUE.
条件JOIN
{T1}[NATURAL][INNER{LEFTRIGHTFULL}[OUTER]]JOIN{T2}{ONsearchconditionUSING(joincolumnlist)}
一个条件JOIN必须通过提供一个(并且只能有一个)NATURAL,ON,或者USING这样的关键字来声明它的连接条件.ON子句接受一个searchcondition,它与一个WHERE子句相同.USING子句接受一个用逗号分隔的字段名列表,连接表中必须都有这些字段,并且用那些字段连接这些表,生成的连接表包含每个共有字段和两个表的所有其它字段.NATURAL是USING子句的缩写,它列出两个表中所有公共的字
段名字.使用USING和NATURAL的副作用是每个连接的字段都只有一份拷贝出现在结果表中(与前面定义的关系演算的JOIN相比较).
[INNER]JOIN
对于T1的每行R1,连接成的表在T2里都有一行满足与R1一起的连接条件.
对于所有JOIN而言,INNER和OUTER都是可选的.INNER是缺省.LEFT,RIGHT,和FULL只用于OUTERJOIN.
LEFT[OUTER]JOIN
首先,执行一次INNERJOIN.然后,如果T1里有一行对任何T2的行都不满足连接条件,那么返回一个连接行,该行的T2的字段为null.
小技巧连接成的表无条件地包含T1里的所有行.
RIGHT[OUTER]JOIN
首先,执行一次INNERJOIN.然后,如果T2里有一行对任何T1的行都不满足连接条件,那么返回一个连接行,该行的T1的字段为null.
小技巧连接成的表无条件地包含T2里的所有行.
FULL[OUTER]JOIN
首先,执行一次INNERJOIN.然后,如果T1里有一行对任何T2的行都不满足连接条件,那么返回一个连接行,该行的T1的字段为null.同样,如果T2里有一行对任何T1的行都不满足连接条件,那么返回一个连接行,该行的T2的字段为null.
小技巧连接成的表无条件地拥有来自T1的每一行和来自T2的每一行.
所有类型的JOIN都可以链接在一起或者嵌套在一起,这时T1和T2都可以是连接生成的表.我们可以使用圆括弧控制JOIN的顺序,如果我们不主动控制,那么连接顺序是从左到右.
1.4.1.3.聚集操作符
SQL提供以一些聚集操作符(如,AVG,COUNT,SUM,MIN,MAX),这些聚集操作符以一个表达式为参数。只要是满足WHERE子句的行,就会计算这个表达式,然后聚集操作符对这个输入数值的集合进行计算.通常,一个聚集对整个SELECT语句计算的结果是生成一个结果.但如果在一个查询里面声明了分组,那么数据库将对每个组进行一次独立的计算,并且聚集结果是按照各个组出现的(见下节).
Example1-5.聚集
果我们想知道表PART里面所有部件的平均价格,我们可以使用下面查询:
SELECTAVG(PRICE)ASAVG_PRICE
FROMPART;
结果是:
AVG_PRICE
-----------
14.5
如果我们想知道在表PART里面存储了多少部件,我们可以使用语句:
SELECTCOUNT(PNO)
FROMPART;
得到:
COUNT
-------
4
1.4.1.4.分组聚集
SQL允许我们把一个表里面的记录分成组。然后上面描述的聚集操作符可以应用于这些组上(也就是说,聚集操作符的值不再是对所有声明的列的值进行操作,而是对一个组的所有值进行操作。这样聚集函数是为每个组独立地进行计算的。)
对记录的分组是通过关键字G
ROUPBY实现的,GROUPBY后面跟着一个定义组的构成的属性列表。如果我们使用语句GROUPBYA1,&;tdot;,Ak我们就把关系分成了组,这样当且仅当两条记录在所有属性A1,&;tdot;,Ak上达成一致,它们才是同一组的。
Example1-6.聚集
如果我们想知道每个供应商销售多少个部件,我们可以这样写查询:
SELECTS.SNO,S.SNAME,COUNT(SE.PNO)
FROMSUPPLIERS,SELLSSE
WHERES.SNO=SE.SNO
GROUPBYS.SNO,S.SNAME;
得到:
SNOSNAMECOUNT
-----+-------+-------
1Smith2
2Jones1
3Adams2
4Blake3
然后我们看一看发生了什么事情。首先生成表SUPPLIER和SELLS的连接:
S.SNOS.SNAMESE.PNO
-------+---------+--------
1Smith1
1Smith2
2Jones4
3Adams1
3Adams3
4Blake2
4Blake3
4Blake4
然后我们把那些属性S.SNO和S.SNAME相同的记录放在组中:
S.SNOS.SNAMESE.PNO
-------+---------+--------
1Smith1
2
--------------------------
2Jones4
--------------------------
3Adams1
3
--------------------------
4Blake2
3
4
在我们的例子里,我们有四个组并且现在我们可以对每个组应用聚集操作符COUNT,生成上面给出的查询的最终结果。
请注意如果要让一个使用GROUPBY和聚集操作符的查询的结果有意义,那么用于分组的属性也必须出现在目标列表中。所有没有在GROUPBY子句里面出现的属性都只能通过使用聚集函数来选择。否则就不会有唯一的数值与其它字段关联.
还要注意的是在聚集上聚集是没有意义的,比如,AVG(MAX(sno)),因为SELECT只做一个回合的分组和聚集.你可以获得这样的结果,方法是使用临时表或者在FROM子句中使用一个子SELECT做第一个层次的聚集.
1.4.1.5.Having
HAVING子句运做起来非常象WHERE子句,只用于对那些满足HAVING子句里面给出的条件的组进行计算。其实,WHERE在分组和聚集之前过滤掉我们不需要的输入行,而HAVING在GROUP之后那些不需要的组.因此,WHERE无法使用一个聚集函数的结果.而另一方面,我们也没有理由写一个不涉及聚集函数的HAVING.如果你的条件不包含聚集,那么你也可以把它写在WHERE里面,这样就可以避免对那些你准备抛弃
的行进行的聚集运算.
Example1-7.Having
如果我们想知道那些销售超过一个部件的供应商,使用下面查询:
SELECTS.SNO,S.SNAME,COUNT(SE.PNO)
FROMSUPPLIERS,SELLSSE
WHERES.SNO=SE.SNO
GROUPBYS.SNO,S.SNAME
HAVINGCOUNT(SE.PNO)1;
andget
SNOSNAMECOUNT
-----+-------+-------
1Smith2
3Adams2
4Blake3
1.4.1.6.子查询
在WHERE和HAVING子句里,允许在任何要产生数值的地方使用子查询(子选择)。这种情况下,该值必须首先来自对子查询的计算。子查询的使用扩展了SQL的表达能力。
Example1-8.子查询
如果我们想知道所有比名为'Screw'的部件贵的部件,我们可以用下面的查询:
SELECT
FROMPART
WHEREPRICE(SELECTPRICEFROMPART
WHEREPNAME='Screw');
结果是:
PNOPNAMEPRICE
-----+---------+--------
3Bolt15
4Cam25
当我们检查上面的查询时会发现出现了两次SELECT关键字。第一个在查询的开头-我们将称之为外层SELECT-而另一个在WHERE子句里面,成为一个嵌入的查询-我们将称之为内层SELECT。对外层SELECT的每条记录都必须先计算内层SELECT。在完成所有计算之后,我们得知名为'Screw'部件的记录的价格,然后我们就可以检查那些价格更贵的记录了。(实际上,在本例中,内层查询只需要执行一次,因为它不依赖于外层查询高等状态.)
如果我们想知道那些不销售任何部件的供应商(比如说,我们想把这些供应商从数据库中删除),我们用:
SELECT
FROMSUPPLIERS
WHERENOTEXISTS
(SELECTFROMSELLSSE
WHERESE.SNO=S.SNO);
在我们的例子里,结果列将是空的,因为每个供应商至少销售一个部件。请注意我们在WHERE子句的内层SELECT里使用了来自外层SELECT的S.SNO。正如前面所说的,子查询为每个外层查询计算一次,也就是说,S.SNO的值总是从外层SELECT的实际记录中取得的。
1.4.1.7.在FROM里面的子查询
一种有些特别的子查询的用法是把它们放在FROM子句里.这个特性很有用,因为这样的子查询可以输出多列和多行,而在表达式里使用的子查询必须生成一个结果.FROM里的子查询还可以让我们获得多于一个回合的分组聚集特性,而不需要求助于临时表.
Example1-9.FROM里面的子查询
如果我们想知道在所有我们的供应商中的最高平均部件价格的那家,我们不能用MAX(AVG(PRICE)),但我们可以这么写:
SELECTMAX(subtable.avgprice)
FROM(SELECTAVG(P.PRICE)ASavgprice
F
ROMSUPPLIERS,PARTP,SELLSSE
WHERES.SNO=SE.SNOAND
P.PNO=SE.PNO
GROUPBYS.SNO)subtable;
这个子查询为每个供应商返回一行(因为它的GROUPBY)然后我们在外层查询对所有行进行聚集.
1.4.1.8.Union,Intersect,Except(联合,相交,相异)
这些操作符分别计算两个子查询产生的元组的联合,相交和集合理论里的相异。
Example1-10.Union,Intersect,Except
下面的例子是UNION的例子:
SELECTS.SNO,S.SNAME,S.CITY
FROMSUPPLIERS
WHERES.SNAME='Jones'
UNION
SELECTS.SNO,S.SNAME,S.CITY
FROMSUPPLIERS
WHERES.SNAME='Adams';
产生结果:
SNOSNAMECITY
-----+-------+--------
2JonesParis
3AdamsVienna
下面是相交(INTERSECT)的例子:
SELECTS.SNO,S.SNAME,S.CITY
FROMSUPPLIERS
WHERES.SNO1
INTERSECT
SELECTS.SNO,S.SNAME,S.CITY
FROMSUPPLIERS
WHERES.SNO3;
产生结果:
SNOSNAMECITY
-----+-------+--------
2JonesParis
两个查询都会返回的元组是那条SNO=2的
最后是一个EXCEPT的例子:
SELECTS.SNO,S.SNAME,S.CITY
FROMSUPPLIERS
WHERES.SNO1
EXCEPT
SELECTS.SNO,S.SNAME,S.CITY
FROMSUPPLIERS
WHERES.SNO3;
结果是:
SNOSNAMECITY
-----+-------+--------
2JonesParis
3AdamsVienna