蒙在股里 发表于 2015-1-16 22:35:08

MYSQL网站制作之操纵数据:中级SQL

怀疑这些功能在MySQL5.0中的成熟性。充其量它们在MySQL中被支持的时间也就一年左右,而在MySQL学习教程其他关系型数据库中则已经存在了近10年的时间。数据作数据:中级SQL
[繁w中文]|文章种别:数据库教程|文章品级:




|宣布日期:2001-3-22木曜日

[计数器|出色博客|邪术心情|博客请求|源码下载|IP查询|投票查询拜访|Html2Js]转自:静态网制造指南www.ckuyun.com本章内容
■创立索引
■SQL中心语句
■汇合函数
■别的经常使用的SQL表达式,函数,和历程



第十章“SQL基本”向你开端先容了SQL。你学会了怎样用SELECT语句举行查询,你还学会了怎样创建本人的表。在这一章里,你将加深你的SQL常识。你将进修怎样创建索引来加速查询速率。你还将学会假如用更多的SQL语句和函数来操纵表中的数据。

创建索引
假定你想找到本书中的某一个句子。你能够一页一页地逐页搜刮,但这会花良多工夫。而经由过程利用本书的索引,你能够很快地找到你要搜刮的主题。
表的索引与附在一本书前面的索引十分类似。它能够极年夜地进步查询的速率。对一个较年夜的表来讲,经由过程加索引,一个一般要消费几个小时来完成的查询只需几分钟就能够完成。因而没有来由对必要频仍查询的表增添索引。
注重:
当你的内存容量或硬盘空间不敷时,大概你不想给一个表增添索引。关于包括索引的数据库,SQLSever必要一个可不雅的分外空间。比方,要创建一个聚簇索引,必要约莫1.2倍于数据巨细的空间。要看一看一个表的索引在数据库中所占的空间巨细,你可使用体系存储历程sp_spaceused,工具名指定为被索引的表名。

聚簇索引和非聚簇索引
假定你已经由过程本书的索引找到了一个句子地点的页码。一旦已晓得了页码后,你极可能漫无目标翻寻这本书,直至找到准确的页码。经由过程随机的翻寻,你终极能够抵达准确的页码。可是,有一种找到页码的更无效的办法。
起首,把书翻到也许一半的中央,假如要找的页码比半本书处的页码小,就书翻到四分之一处,不然,就把书翻到四分之三的中央。经由过程这类办法,你能够持续把书分红更小的部分,直至找到准确的页码四周。这是找到册页的十分无效的一种办法。
SQLSever的表索引以相似的体例事情。一个表索引由一组页构成,这些页组成了一个树形布局。根页经由过程指向别的两个页,把一个表的纪录从逻辑上分红和两个部分。而根页所指向的两个页又分离把纪录支解成更小的部分。每一个页都把纪录分红更小的支解,直至抵达叶级页。
索引有两品种型:聚簇索引和非聚簇索引。在聚簇索引中,索引树的叶级页包括实践的数据:纪录的索引按次与物理按次不异。在非聚簇索引中,叶级页指向表中的纪录:纪录的物理按次与逻辑按次没有一定的接洽。
聚簇索引十分象目次表,目次表的按次与实践的页码按次是分歧的。非聚簇索引则更象书的尺度索引表,索引表中的按次一般与实践的页码按次是纷歧致的。一本书大概有多个索引。比方,它大概同时有主题索引和作者索引。一样,一个表能够有多个非聚簇索引。
一般情形下,你利用的是聚簇索引,可是你应当对两品种型索引的优弱点都有所了解。
每一个表只能有一个聚簇索引,由于一个表中的纪录只能以一种物理按次寄存。一般你要对一个表依照标识字段创建聚簇索引。可是,你也能够对别的范例的字段创建聚簇索引,如字符型,数值型和日期工夫型字段。
从创建了聚簇索引的表中掏出数据要比创建了非聚簇索引的表快。当你必要掏出必定局限内的数据时,用聚簇索引也比用非聚簇索引好。比方,假定你用一个表来纪录会见者在你网点上的举动。假如你想掏出在必定工夫段内的登录信息,你应当对这个表的DATETIME型字段创建聚簇索引。
对聚簇索引的次要限定是每一个表只能创建一个聚簇索引。可是,一个表能够有不止一个非聚簇索引。实践上,对每一个表你最多能够创建249个非聚簇索引。你也能够对一个表同时创建聚簇索引和非聚簇索引。
假设你不但想依据日期,并且想依据用户名从你的网点举动日记中取数据。在这类情形下,同时创建一个聚簇索引和非聚簇索引是无效的。你能够对日期工夫字段创建聚簇索引,对用户名字段创建非聚簇索引。假如你发明你必要更多的索引体例,你能够增添更多的非聚簇索引。
非聚簇索引必要大批的硬盘空间和内存。别的,固然非聚簇索引能够进步从表中取数据的速率,它也会下降向表中拔出和更新数据的速率。每当你改动了一个创建了非聚簇索引的表中的数据时,必需同时更新索引。因而你对一个表创建非聚簇索引时要稳重思索。假如你估计一个表必要频仍地更新数据,那末不要对它创建太多非聚簇索引。别的,假如硬盘和内存空间无限,也应当限定利用非聚簇索引的数目。

索引属性
这两品种型的索引都有两个主要属性:你能够用二者中任一品种型同时对多个字段创建索引(复合索引);两品种型的索引都能够指定为独一索引。
你能够对多个字段创建一个复合索引,乃至是复合的聚簇索引。假设有一个表纪录了你的网点会见者的姓和名字。假如你但愿依据完全姓名从表中取数据,你必要创建一个同时对姓字段和名字字段举行的索引。这和分离对两个字段创建独自的索引是分歧的。当你但愿同时对不止一个字段举行查询时,你应当创建一个对多个字段的索引。假如你但愿对各个字段举行分离查询,你应当对各字段创建自力的索引。
两品种型的索引都能够被指定为独一索引。假如对一个字段创建了独一索引,你将不克不及向这个字段输出反复的值。一个标识字段会主动成为独一值字段,但你也能够对别的范例的字段创建独一索引。假定你用一个表来保留你的网点的用户暗码,你固然不但愿两个用户有不异的暗码。经由过程强迫一个字段成为独一值字段,你能够避免这类情形的产生。

用SQL创建索引
为了给一个表创建索引,启动义务栏SQLSever程序组中的ISQL/w程序。进进查询窗口后,输出上面的语句:

CREATEINDEXmycolumn_indexONmytable(myclumn)

这个语句创建了一个名为mycolumn_index的索引。你能够给一个索引发任何名字,但你应当在索引名中包括所索引的字段名,这对你未来弄分明创建该索引的企图是有匡助的。
注重:
在本书中你实行任何SQL语句,城市收到以下的信息:
Thiscommanddidnotreturndata,anditdidnotreturnanyrows
这申明该语句实行乐成了。
索引mycolumn_index对表mytable的mycolumn字段举行。这是个非聚簇索引,也是个非独一索引。(这是一个索引的缺省属性)
假如你必要改动一个索引的范例,你必需删除本来的索引偏重建一个。创建了一个索引后,你能够用上面的SQL语句删除它:

DROPINDEXmytable.mycolumn_index

注重在DROPINDEX语句中你要包括表的名字。在这个例子中,你删除的索引是mycolumn_index,它是表mytable的索引。
要创建一个聚簇索引,可使用关头字CLUSTERED。)记着一个表只能有一个聚簇索引。(这里有一个怎样对一个表创建聚簇索引的例子:

CREATECLUSTEREDINDEXmycolumn_clust_indexONmytable(mycolumn)

假如表中有反复的纪录,当你试图用这个语句创建索引时,会呈现毛病。可是有反复纪录的表也能够创建索引;你只需利用关头字ALLOW_DUP_ROW把这一点告知SQLSever便可:

CREATECLUSTEREDINDEXmycolumn_cindexONmytable(mycolumn)
WITHALLOW_DUP_ROW

这个语句创建了一个同意反复纪录的聚簇索引。你应当只管制止在一个表中呈现反复纪录,可是,假如已呈现了,你可使用这类办法。
要对一个表创建独一索引,可使用关头字UNIQUE。对聚簇索引和非聚簇索引都可使用这个关头字。这里有一个例子:

CREATEUNIQUECOUSTEREDINDEXmyclumn_cindexONmytable(mycolumn)

这是你将常常利用的索引创建语句。不管什么时候,只需能够,你应当只管对一个对一个表创建独一聚簇索引来加强查询操纵。
最初,要创建一个对多个字段的索引──复合索引──在索引创建语句中同时包括多个字段名。上面的例子对firstname和lastname两个字段创建索引:

CREATEINDEXname_indexONusername(firstname,lastname)

这个例子对两个字段创建了单个索引。在一个复合索引中,你最多能够对16个字段举行索引。

用事件办理器创建索引
用事件办理器创建索引比用SQL语句简单的多。利用事件办理器,你能够看到已创建的索引的列表,并能够经由过程图形界面选择索引选项。
利用事件办理器你能够用两种体例创建索引:利用ManageTables窗口或利用ManageIndexes窗口。
要用ManageTables窗口创建一个新索引,单击按钮AdvancedOptions(它看起来象一个后面有一加号的表)。如许就翻开了AdvancedOptions对话框。这个对话框有一部分标名为PrimaryKey(见1.1)。

1。1

要创建一个新索引,从下拉列表当选择你想对之创建索引的字段名。假如你想创建一个对多字段的索引,你能够选择多个字段名。你还能够选择索引是聚簇的仍是非聚簇的。在保留表信息后,索引会主动被创建。在ManageTables窗口中的字段名中间,会呈现一把钥匙。
你已为你的表创建了“主索引”。主索引必需对不包括空值的字段创建。别的,主索引强迫一个字段成为独一值字段。
要创建没有这些限定的索引,你必要利用ManageIndexes窗口。从菜单当选择Manage|Indexes,翻开ManageIndexes窗口。在ManageIndexes窗口中,你能够经由过程下拉框选择表和特定的索引。(见1.2)。要创建一个新索引,从Index下拉框当选择NewIndex.,然后就能够选择要对之创建索引的字段。单击按钮Add,把字段加人到索引中。

1。2

你能够为你的索引选择很多分歧的选项。比方,你能够选择该索引是聚簇的仍是非聚簇的。你还能够指定该索引为独一索引。计划好索引后,单击按钮Build,创建该索引。

注重:
独一索引是指该字段不克不及有反复的值,而不是只能创建这一个索引。

SQL中心语句
在第十章,你学会了怎样用SQLSELECT语句从一个表中取数据。可是,到如今为止,还没有会商怎样增加,修正或删除表中的数据。在这一节中,你将进修这些内容。

拔出数据
向表中增加一个新纪录,你要利用SQLINSERT语句。这里有一个怎样利用这类语句的例子:

INSERTmytable(mycolumn)VALUES(‘somedata’)

这个语句把字符串’somedata’拔出表mytable的mycolumn字段中。将要被拔出数据的字段的名字在第一个括号中指定,实践的数据在第二个括号中给出。
INSERT语句的完全句法以下:

INSERT{table_name|view_name}[(column_list)]{DEFAULTVALUES|
Values_list|select_statement}

假如一个表有多个字段,经由过程把字段名和字段值用逗号离隔,你能够向一切的字段中拔出数据。假定表mytable有三个字段first_column,second_column,和third_column。上面的INSERT语句增加了一条三个字段都有值的完全纪录:

INSERTmytable(first_column,second_column,third_column)
VALUES(‘somedata’,’somemoredata’,’yetmoredata’)

注重:
你可使用INSERT语句向文本型字段中拔出数据。可是,假如你必要输出很长的字符串,你应当利用WRITETEXT语句。这部份内容对本书来讲太初级了,因而不加会商。要懂得更多的信息,请参考MicrosoftSQLSever的文档。

假如你在INSERT语句中只指定两个字段和数据会怎样呢?换句话说,你向一个表中拔出一条新纪录,但有一个字段没有供应数据。在这类情形下,有上面的四种大概:
■假如该字段有一个缺省值,该值会被利用。比方,假定你拔出新纪录时没有给字段third_column供应数据,而这个字段有一个缺省值’somevalue’。在这类情形下,当新纪录创建时会拔出值’somevalue’。
■假如该字段能够承受空值,并且没出缺省值,则会被拔出空值。
■假如该字段不克不及承受空值,并且没出缺省值,就会呈现毛病。你会收到毛病信息:
Thecolumnintablemytablemaynotbenull.
■最初,假如该字段是一个标识字段,那末它会主动发生一个新值。当你向一个有标识字段的表中拔出新纪录时,只需疏忽该字段,标识字段会给本人赋一个新值。

注重:
向一个有标识字段的表中拔出新纪录后,你能够用SQL变量@@identity来会见新纪录
的标识字段的值。思索以下的SQL语句:

INSERTmytable(first_column)VALUES(‘somevalue’)

INSERTanothertable(another_first,another_second)
VALUES(@@identity,’somevalue’)

假如表mytable有一个标识字段,该字段的值会被拔出表anothertable的another_first字段。这是由于变量@@identity老是保留最初一次拔出标识字段的值。
字段another_first应当与字段first_column有不异的数据范例。可是,字段another_first不克不及是应当标识字段。Another_first字段用来保留字段first_column的值。

删除纪录
要从表中删除一个或多个纪录,必要利用SQLDELETE语句。你能够给DELETE语句供应WHERE子句。WHERE子句用来选择要删除的纪录。比方,上面的这个DELETE语句只删除字段first_column的值即是’DeleteMe’的纪录:

DELETEmytableWHEREfirst_column=’DeltetMe’

DELETE语句的完全句法以下:

DELETE{table_name|view_name}

在SQLSELECT语句中可使用的任何前提都能够在DELECT语句的WHERE子句中利用。比方,上面的这个DELETE语句只删除那些first_column字段的值为’goodbye’或second_column字段的值为’solong’的纪录:

DELETEmytableWHEREfirst_column=’goodby’ORsecond_column=’solong’

假如你不给DELETE语句供应WHERE子句,表中的一切纪录都将被删除。你不该该有这类设法。假如你想删除应当表中的一切纪录,应利用第十章所讲的TRUNCATETABLE语句。

注重:
为何要用TRUNCATETABLE语句取代DELETE语句?当你利用TRUNCATETABLE语句时,纪录的删除是不作纪录的。也就是说,这意味着TRUNCATETABLE要比DELETE快很多。

更新纪录
要修正表中已存在的一条或多笔记录,应利用SQLUPDATE语句。同DELETE语句一样,UPDATE语句可使用WHERE子句来选择更新特定的纪录。请看这个例子:

UPDATEmytableSETfirst_column=’Updated!’WHEREsecond_column=’UpdateMe!’

这个UPDATE语句更新一切second_column字段的值为’UpdateMe!’的纪录。对一切被选中的纪录,字段first_column的值被置为’Updated!’。
上面是UPDATE语句的完全句法:

UPDATE{table_name|view_name}SET[{table_name|view_name}]
{column_list|variable_list|variable_and_column_list}
[,{column_list2|variable_list2|variable_and_column_list2}…
[,{column_listN|variable_listN|variable_and_column_listN}]]


注重:
你能够对文本型字段利用UPDATE语句。可是,假如你必要更新很长的字符串,应利用UPDATETEXT语句。这部份内容对本书来讲太初级了,因而不加会商。要懂得更多的信息,请参考MicrosoftSQLSever的文档。


假如你不供应WHERE子句,表中的一切纪录都将被更新。偶然这是有效的。比方,假如你想把表titles中的一切书的代价更加,你可使用以下的UPDATE语句:
你也能够同时更新多个字段。比方,上面的UPDATE语句同时更新first_column,second_column,和third_column这三个字段:

UPDATEmytableSETfirst_column=’Updated!’
Second_column=’Updated!’
Third_column=’Updated!’
WHEREfirst_column=’UpdateMe1’

技能:
SQL疏忽语句中过剩的空格。你能够把SQL语句写成任何你最简单读的格局。


用SELECT创立纪录和表
你大概已注重到,INSERT语句与DELETE语句和UPDATE语句有一点分歧,它一次只操纵一个纪录。但是,有一个办法可使INSERT语句一次增加多个纪录。要作到这一点,你必要把INSERT语句与SELECT语句分离起来,象如许:

INSERTmytable(first_column,second_column)
SELECTanother_first,another_second
FROManothertable
WHEREanother_first=’CopyMe!’

这个语句从anothertable拷贝纪录到mytable.只要表anothertable中字段another_first的值为’CopyMe!’的纪录才被拷贝。
当为一个表中的纪录创建备份时,这类情势的INSERT语句长短常有效的。在删除一个表中的纪录之前,你能够先用这类办法把它们拷贝到另外一个表中。
假如你必要拷贝全部表,你可使用SELECTINTO语句。比方,上面的语句创立了一个名为newtable的新表,该表包括表mytable的一切数据:

SELECT*INTOnewtableFROMmytable

你也能够指定只要特定的字段被用来创立这个新表。要做到这一点,只需在字段列表中指定你想要拷贝的字段。别的,你可使用WHERE子句来限定拷贝到新表中的纪录。上面的例子只拷贝字段second_columnd的值即是’CopyMe!’的纪录的first_column字段。

SELECTfirst_columnINTOnewtable
FROMmytable
WHEREsecond_column=’CopyMe!’

利用SQL修正已创建的表是很坚苦的。比方,假如你向一个表中增加了一个字段,没有简单的举措往复除它。别的,假如你不当心把一个字段的数据范例给错了,你将没有举措改动它。可是,利用本节中报告的SQL语句,你能够绕过这两个成绩。
比方,假定你想从一个表中删除一个字段。利用SELECTINTO语句,你能够创立该表的一个拷贝,但不包括要删除的字段。这使你既删除该字段,又保存了不想删除的数据。
假如你想改动一个字段的数据范例,你能够创立一个包括准确数据范例字段的新表。创立好该表后,你就能够分离利用UPDATE语句和SELECT语句,把本来表中的一切数据拷贝到新表中。经由过程这类办法,你既能够修正表的布局,又能保留原本的数据。

汇合函数
到如今为止,你只进修了怎样依据特定的前提从表中掏出一条或多笔记录。可是,假设你想对一个表中的纪录举行数据统计。比方,假如你想统计存储在表中的一次平易近意检验的投票了局。大概你想晓得一个会见者在你的站点上均匀消费了几工夫。要对表中的任何范例的数据举行统计,都必要利用汇合函数。
MicrosoftSQL撑持五品种型的汇合函数。你能够统计纪录数量,均匀值,最小值,最年夜值,大概乞降。当你利用一个汇合函数时,它只前往一个数,该数值代表这几个统计值之一。

注重:
要在你的ASP网页中利用汇合函数的前往值,你必要给该值起一个名字。要作到这一点,你能够在SELECT语句中,在汇合函数前面紧跟一个字段名,以下例所示:

SELECTAVG(vote)‘the_average’FROMopinion

在这个例子中,vote的均匀值被定名为the_average。如今你能够在你的ASP网页的数据库办法中利用这个名字。

统计字段值的数量
函数COUNT()大概是最有效的汇合函数。你能够用这个函数来统计一个表中有几笔记录。这里有一个例子:

SELECTCOUNT(au_lname)FROMauthors

这个例子盘算表authors中名字(lastname)的数量。假如不异的名字呈现了不止一次,该名字将会被盘算屡次。假如你想晓得名字为某个特定值的作者有几个,你可使用WHERE子句,以下例所示:

SELECTCOUNT(au_lname)FROMauthorsWHEREau_lname=’Ringer’

这个例子前往名字为’Ringer’的作者的数量。假如这个名字在表authors中呈现了两次,则次函数的前往值是2。
假设你想晓得有分歧名字的作者的数量。你能够经由过程利用关头字DISTINCT来失掉该数量。以下例所示:

SELECTCOUNT(DISTINCTau_lname)FROMauthors

假如名字’Ringer’呈现了不止一次,它将只被盘算一次。关头字DISTINCT决意了只要互不不异的值才被盘算。
一般,当你利用COUNT()时,字段中的空值将被疏忽。一样平常来讲,这恰是你所但愿的。可是,假如你仅仅想晓得表中纪录的数量,那末你必要盘算表中一切的纪录─不论它是不是包括空值。上面是一个怎样做到这一点的例子:

SELECTCOUNT(*)FROMauthors

注重函数COUNT()没有指定任何字段。这个语句盘算表中一切纪录所数量,包含有空值的纪录。因而,你不必要指定要被盘算的特定字段。
函数COUNT()在良多分歧情形下是有效的。比方,假定有一个表保留了对你站点的质量举行平易近意查询拜访的了局。这个表有一个名为vote的字段,该字段的值要末是0,要末是1。0暗示否决票,1暗示同意票。要断定同意票的数目,你能够一切上面的SELECT语句:

SELECTCOUNT(vote)FROMopinion_tableWHEREvote=1

盘算字段的均匀值
利用函数COUNT(),你能够统计一个字段中有几个值。但偶然你必要盘算这些值的均匀值。利用函数AVG(),你能够前往一个字段中一切值的均匀值。
假设你对你的站点举行一次较为庞大的平易近意查询拜访。会见者能够在1到10之间投票,暗示他们喜好你站点的水平。你把投票了局保留在名为vote的INT型字段中。要盘算你的用户投票的均匀值,你必要利用函数AVG():

SELECTAVG(vote)FROMopinion

这个SELECT语句的前往值代表用户对你站点的均匀喜好水平。函数AVG()只能对数值型字段利用。这个函数在盘算均匀值时也疏忽空值。

盘算字段值的和
假定你的站点被用来出卖卡片,已运转了两个月,是该盘算赚了几钱的时分了。假定有一个名为orders的表用来纪录一切会见者的定购信息。要盘算一切定购量的总和,你可使用函数SUM():

SELECTSUM(purchase_amount)FROMorders

函数SUM()的前往值代表字段purchase_amount中一切值的均匀值。字段purchase_amount的数据范例大概是MONEY型,但你也能够对别的数值型字段利用函数SUM()。

前往最年夜值或最小值
再一次假定你有一个表用来保留对你的站点举行平易近意查询拜访的了局。会见者能够选择从1到10的值来暗示他们对你站点的评价。假如你想晓得会见者对你站点的最高评价,你可使用以下的语句:

SELECTMAX(vote)FROMopinion

你大概但愿有人对你的站点赐与了很高的评价。经由过程函数MAX(),你能够晓得一个数值型字段的一切值中的最年夜值。假如有人对你的站点投了数字10,函数MAX()将前往该值。
另外一方面,假设你想晓得会见者对你站点的的最低评价,你可使用函数MIN(),以下例所示:

SELECTMIN(vote)FROMopinion

函数MIN()前往一个字段的一切值中的最小值。假如字段是空的,函数MIN()前往空值。

别的经常使用的SQL表达式,函数,和历程
这一节将先容一些别的的SQL手艺。你将进修怎样从表中掏出数据,其某个字段的值处在必定的局限,你还将进修怎样把字段值从一品种型转换成另外一品种型,怎样操纵字符串和日期工夫数据。最初,你将学会一个发送邮件的复杂办法。

经由过程婚配必定局限的值来掏出数据
假定你有一个表用来保留对你的站点举行平易近意查询拜访的了局。如今你想向一切对你的站点的评价在7到10之间的会见者发送书面的感激信。要失掉这些人的名字,你可使用以下的SELECT语句:

SELECTusernameFROMopinionWHEREvote>6andvote<11

这个SELECT语句会完成你的请求。你利用上面的SELECT语句也能够失掉一样的了局:

SELECTusernameFROMopinionWHEREvoteBETWEEN7AND10

这个SELECT语句与上一个语句是等价的。利用哪种语句是编程作风的成绩,但你会发明利用表达式BETWEEN的语句更容易读。
如今假定你只想掏出对你的站点投了1大概10的会见者的名字。要从表opinion中掏出这些名字,你可使用以下的SELECT语句:

SELECTusernameFROMopinionWHEREvote=1orvote

这个SELECT语句会前往准确的了局,没有来由不利用它。可是,存在一种等价的体例。利用以下的SELECT能够失掉不异的了局:

SELECTusernameFROMopinionWHEREvoteIN(1,10)

注重表达式IN的利用。这个SELECT语句只掏出vote的值即是括号中的值之一的纪录。
你也能够利用IN来婚配字符数据。比方,假定你只想掏出BillGates或PresidentClinton的投票值。你可使用以下的SELECT语句:

SELECTvoteFROMopinionWHEREusernameIN(‘BillGates’,’PresidentClinton’)

最初,你能够在利用BETWEEN或IN的同时利用表达式NOT。比方,要掏出那些投票值不在7到10之间的人的名字,你可使用以下的SELECT语句:

SELECTusernameFROMopinionWHEREvoteNOTBETWEEN7and10

要拔取那些某个字段的值不在一列值当中的纪录,你能够同时利用NOT和IN,以下例所示:

SELECTvoteFROMopinion
WHEREusernameNOTIN(‘BillGates’,’PresidentClinton’)

你不是必需在SQL语句中利用BETWEEN或IN,可是,要使你的查询更靠近天然言语,这两个表达式是有匡助的。

转换数据
SQLSever充足壮大,能够在必要的时分把年夜部分数值从一品种型转换为另外一品种型。比方,要对照SMALLINT型和INT型数据的巨细,你不必要举行显式的范例转换。SQLSever会为你完成这项事情。可是,当你想在字符型数据和别的范例的数据之间举行转换时,你切实其实必要本人举行转换操纵。比方,假定你想从一个MONEY型字段中掏出一切的值,并在了局前面加上字符串“USDollars”。你必要利用函数CONVERT(),以下例所示:

SELECTCONVERT(CHAR(8),price)+’USDollars’FROMorders

函数CONVERT()带有两个变量。第一个变量指定了数据范例和长度。第二个变量指定了要举行转换的字段。在这个例子中,字段price被转换发展度为8个字符的CHAR型字段。字段price要被转换成字符型,才能够在它前面毗连上字符串’USDollars’。
当向BIT型,DATETIME型,INT型,大概NUMERIC型字段增加字符串时,你必要举行一样的转换操纵。比方,上面的语句在一个SELECT语句的查询了局中到场字符串’Thevoteis’,该SELECT语句前往一个BIT型字段的值:

SELECT‘Thevoteis’+CONVERT(CHAR(1),vote)FROMopinion

上面是这个语句的了局示例:

Thevoteis1
Thevoteis1
Thevoteis0
(3row(s)affected)

假如你不举行显式的转换,你会收到以下的毛病信息:
Implicitconversionfromdatatype‘varchar’to‘bit’isnotallowec.
UsetheCONVERTfunctiontorunthisquery.

操纵字符串数据
SQLSever有很多函数和表达式,使你能对字符串举行风趣的操纵,包含林林总总的形式婚配和字符转换。在这一节中,你将进修怎样利用最主要的字符函数和表达式。

婚配通配符
假定你想创建一个与Yahoo功效类似的Internet目次。你能够创建一个表用来保留一系列的站点称号,一致资本定位器(URL),形貌,和种别,并同意会见者经由过程在HTMLform中输出关头字来检索这些内容。
假设有一个会见者想从这个目次中失掉其形貌中包括关头字tradingcard的站点的列表。要掏出准确的站点列表,你大概试图利用如许的查询:

SELECTsite_nameFROMsite_directoryWHEREsite_desc=’tradingcard’

这个查询能够事情。可是,它只能前往那些其形貌中只要tradingcard这个字符串的站点。比方,一个形貌为Wehavethegreatestcollectionoftradingcardsintheworld!的站点不会被前往。
要把一个字符串与另外一个字符串的一部分相婚配,你必要利用通配符。你利用通配符和关头字LIKE来完成形式婚配。上面的语句利用通配符和关头字LIKE重写了下面的查询,以前往一切准确站点的名字:

SELECTSITE_nameFROMsite_directory
WHEREsite_descLIKE‘%tradingcark%’

在这个例子中,一切其形貌中包括表达式tradingcard的站点都被前往。形貌为Wehavethegreatestcollectionoftradingcardsintheworld!的站点也被前往。固然,假如一个站点的形貌中包括Iamtradingcardboardboxesonline,该站点的名字也被前往。
注重本例中百分号的利用。百分号是通配符的例子之一。它代表0个或多个字符。经由过程把tradingcard括在百分号中,一切个中嵌有字符串tradingcard的字符串都被婚配。
如今,假定你的站点目次变得太年夜而不克不及在一页中完整显现。你决意把目次分红两部分。在第一页,你想显现一切首字母在A到M之间的站点。在第二页,你想显现一切首字母在N到Z之间的站点。要失掉第一页的站点列表,你可使用以下的SQL语句:

SELECTsite_nameFROMsite_directoryWHEREsite_nameLIKE‘%’

在这个例子中利用了表达式,只掏出那些首字母在A到M之间的站点。中括号([])用来婚配处在指定局限内的单个字符。要失掉第二页中显现的站点,应利用这个语句:

SELECTsite_nameFROMsite_directory
WHEREsite_nameLIKE‘%’

在这个例子中,括号中的表达式代表任那边在N到Z之间的单个字符。
假定你的站点目次变得更年夜了,你如今必要把目次分红更多页。假如你想显现那些以A,B或C开首的站点,你能够用上面的查询来完成:

SELECTsite_nameFROMsite_directoryWHEREsite_nameLIKE‘%’

在这个例子中,括号中的表达式不再指定一个局限,而是给出了一些字符。任何一个其名字以这些字符中的任一个开首的站点都将被前往。
经由过程在括号内的表达式中同时包括一个局限和一些指定的字符,你能够把这两种办法分离起来。比方,用上面的这个查询,你能够掏出那些首字母在C到F之间,大概以字母Y开首的站点:

SELECTsite_nameFROMsite_directoryWHEREsite_nameLIKE‘%’

在这个例子中,名字为Collegescape和Yahoo的站点会被拔取,而名字为Magicw3的站点则不会被拔取。
你也能够利用脱字符(^)来扫除特定的字符。比方,要失掉那些名字不以Y开首的站点,你可使用以下的查询:

SELECTsite_nameFROMsite_directoryWHEREsite_nameLIKE‘[^Y]%’

对给定的字符或字符局限都可以利用脱字符。
最初,经由过程利用下划线字符(_),你能够婚配任何单个字符。比方,上面这个查询前往每个其名字的第二个字符为任何字母的站点:

SELECTsite_nameFROMsite_directoryWHEREsite_nameLIKE‘M_crosoft’

这个例子既前往名为Microsoft的站点,也前往名为Macrosoft的站点。可是,名字为Moocrosoft的站点则不被前往。与通配符’%’分歧,下划线只代表单个字符。

注重:
假如你想婚配百分号或下划线字符自己,你必要把它们括在方括号中。假如你想婚配连字符(-),应把它指定为方括号中的第一个字符。假如你想婚配方括号,应把它们也括在方括号中。比方,上面的语句前往一切其形貌中包括百分号的站点:

SELECTsite_nameFROMsite_directoryWHEREsite_descLIKE‘%[%]%’
婚配发音
MicrosoftSQL有两个同意你依照发音来婚配字符串的函数。函数SOUNDEX()给一个字符串分派一个音标码,函数DIFFERENCE()依照发音对照两个字符串。当你不晓得一个名字切实其实切拼写,但几晓得一点它的发音时,利用这两个函数将有助于你掏出该纪录。
比方,假如你创建一个Internet目次,你大概想增添一个选项,同意会见者依照站点名的发音来搜刮站点,而不是按名字的拼写。思索以下的语句:

SELECTsite_nameFROMsite_directory
WHEREDIFFERENCE(site_name,‘Microsoft’>3

这个语句利用函数DEFFERENCE()来获得其名字的发音与Microsoft十分类似的站点。函数DIFFERENCE()前往一个0到4之间的数字。假如该函数前往4,暗示发音十分邻近;假如该函数前往0,申明这两个字符串的发音相差很年夜。
比方,下面的语句将前往站点名Microsoft和Macrosoft。这两个名字的发音与Microsoft都很类似。假如你把上一语句中的年夜于3改成年夜于2,那末名为Zicrosoft和Megasoft的站点也将被前往。最初,假如你只必要不同品级年夜于1便可,则名为Picosoft和Minisoft的站点也将被婚配。
要深切懂得函数DIFFERENCE()是怎样事情的,你能够用函数SOUNDEX()来前往函数DIFFERENCE()所利用的音标码。这里有一个例子:

SELECTsite_name‘sitename’,SOUNDEX(site_name)‘soundslike’

这个语句拔取字段site_name的一切数据及其音标码。上面是这个查询的了局:

sitenamesoundslike
……………………………………………………………….
YahooY000
MahooM000
MicrosoftM262
MacrosoftM262
MinisoftM521
MicroshoftM262
ZicrosoftZ262
ZaposoftZ121
MillisoftM421
NanosoftN521
MegasoftM221
PicosoftP221
(12row(s)affected)

假如你细心看一下音标码,你会注重到音标码的第一个字母与字段值的第一个字母不异。比方,Yahoo和Mahoo的音标码只要第一个字母分歧。你还能够发明Microsoft和Macrosoft的音标码完整不异。
函数DIFFERENDE()对照两个字符串的第一个字母和一切的子音字母。该函数疏忽任何元音字母(包含y),除非一个元音字母是一个字符串的第一个字母。
不幸的是,利用SOUNDEX()和DIFFERENCE()有一个完善。WHERE子句中包括这两个函数的查询实行起来效果欠好。因而,你应当当心利用这两个函数。

删除空格
有两个函数,TTRIM()和LTRIM(),能够用来从字符串中剪失落空格。函数LTRIM()往除应当字符串后面的一切空格;函数RTRIM()往除一个字符串尾部的一切空格。这里有一个任何利用函数RTRIM()的例子:

SELECTRTRIM(site_name)FROMsite_directory

在这个例子中,假如任何一个站点的名字尾部有过剩的空格,过剩的空格将从查询了局中删往。
你能够嵌套利用这两个函数,把一个字符串前后的空格同时删往:

SELECTLTRIM(RTRIM(site_name)FROMsite_directory

你会发明,在从CHAR型字段中剪失落过剩的空格时,这两个函数十分有效。记着,假如你把一个字符串保留在CHAR型字段中,该字符串会被追加过剩的空格,以婚配该字段的长度。用这两个函数,你能够往失落无用的空格,从而办理这个成绩。

操纵日期和工夫
日期和工夫函数对创建一个站点长短常有效的。站点的仆人常常对一个表中的数据什么时候被更新感乐趣。经由过程日期和工夫函数,你能够在毫秒级跟踪一个表的改动。

前往以后日期和工夫
经由过程函数GETDATE(),你能够取得以后的日期和工夫。比方,语句SELECTGETDATE()前往以下的了局:
……………………………..
NOV3019973:29AM
(1row(s)affected)

明显,假如你未来利用这个函数,你失掉的日期将比这个工夫晚,大概梗早。
函数GETDATE()能够用来作为DATEDIME()型字段的缺省值。这对拔出纪录时保留事先的工夫是有效的。比方,假定有一个表用来保留你站点上的举动日记。每当有一个会见者会见到你的站点时,就在表中增加一条新纪录,记下会见者的名字,举动,和举行会见的工夫。要创建一个表,个中的纪录包括有以后的日期和工夫,能够增加一个DATETIME型字段,指定其缺省值为函数GETDATE()的前往值,就象如许:

CREATETABLEsite_log(
usernameVARCHAR(40),
useractivityVARCHAR(100),
entrydateDATETIMEDEFAULTGETDATE())

转换日期和工夫
你大概已注重到,在上一节的例子中,函数GETDATE()的前往值在显现时只显现到秒。实践上,SQLSever外部工夫能够准确到毫秒级(切实地说,能够准确到3.33毫秒)。
要失掉分歧格局的日期和工夫,你必要利用函数CONVERT()。比方,当上面的这个语句实行时,显现的工夫将包含毫秒:

SELECTCONVERT(VARCHAR(30),GETDATE(),9)

注重例子中数字9的利用。这个数字指了然在显现日期和工夫时利用哪一种日期和工夫格局。当这个语句实行时,将显现以下的日期和工夫:
…………………………………..
Nov3019973:29:55:170AM
(1row(s)affected)

在函数CONVERT()中你可使用很多种分歧作风的日期和工夫格局。表11.1显现了一切的格局。

表11.1日期和工夫的范例
范例值尺度输入
0Defaultmonddyyyyhh:miAM
1USAmm/dd/yy
2ANSIyy.mm.dd
3British/Frenchdd/mm/yy
4Germandd.mm.yy
5Italiandd-mm-yy
6-ddmonyy
7-mondd,yy
8-hh:mi:ss
9Default+milliseconds--monddyyyy
hh:mi:ss:mmmAM(or)
10USAmm-dd-yy
11JAPANyy/mm/dd
12ISOyymmdd
13EuropeDefault+milliseconds--ddmonyyyy
hh:mi:ss:mmm(24h)
14-hh:mi:ss:mmm(24h)

范例0,9,和13老是前往四位的年。对别的范例,要显现世纪,把style值加上100。范例13和14前往24小不时钟的工夫。范例0,7,和13前往的月份用三位字符暗示(用Nov代表November).

对表11.1中所列的每种格局,你能够把范例值加上100来显现有世纪的年(比方,00年将显现为2000年)。比方,要按日本尺度显现日期,包含世纪,你应利用以下的语句:

SELECTCONVERT(VARCHAR(30),GETDATE(),111)

在这个例子中,函数CONVE如IBM公司最近宣布让渠道合作伙伴分销其SaaS应用程序的新计划。微软认为MySQL学习教程是销售其云计算服务的重要组成部分。然而即使有这种趋势,DBaaS仍然不同于内部数据库,解决方案提供商必须认识到这一点;否则,他们不仅仅是丢失几个客户,而是要失去的更多。

愤怒的大鸟 发表于 2015-1-19 17:48:46

无法深入到数据库系统层面去了解和探究

海妖 发表于 2015-1-24 15:35:31

不好!如果出了错;不好调试;不好处理!其实web开发将代码分为3层:web层;业务逻辑层和数据访问层;一般对数据库的操作都在数据访问层来做;这样便于调试和维护!而且将来如果是换了数据库的话;你只需要改数据层的代码;其他层的基本可以不变!要是你在jsp中直接调用sql数据库;那么如果换了数据库呢?岂不都要改?如果报了异常呢?怎么做异常处理?

爱飞 发表于 2015-2-1 21:02:22

语句级快照和事务级快照终于为SQLServer的并发性能带来了突破。个人感觉语句级快照大家应该应用。事务级快照,如果是高并发系统还要慎用。如果一个用户总是被提示修改不成功要求重试时,会杀人的!

小女巫 发表于 2015-2-7 15:08:53

对于微软系列的东西除了一遍遍尝试还真没有太好的办法

金色的骷髅 发表于 2015-2-22 11:04:56

数据库物理框架没有变动undo和redo都放在数据库得transaction中,个人感觉是个败笔。如果说我们在设计数据库的时候考虑分多个数据库,可能能在一定程度上避免I/O效率问题。

若相依 发表于 2015-3-7 00:09:42

索引视图2k就有。但是2005对其效率作了一些改进但是schema.viewname的作用域真是太限制了它的应用面。还有一大堆的环境参数和种种限制都让人对它有点却步。

活着的死人 发表于 2015-3-13 23:09:31

入门没那么困难,精通没那么容易

仓酷云 发表于 2015-3-20 21:30:59

如果我们从集合论(关系代数)的角度来看,一张数据库的表就是一组数据元的关系,而每个SQL语句会改变一种或数种关系,从而产生出新的数据元的关系(即产生新的表)。
页: [1]
查看完整版本: MYSQL网站制作之操纵数据:中级SQL