什么是SQL?SQL指结构化查询语言SQL使我们有能力访问数据库SQL是一种ANSI的标准计算机语言
编者注:ANSI,美国国家标准化组织
SQL能做什么?SQL面向数据库执行查询SQL可从数据库取回数据SQL可在数据库中插入新的纪录SQL可更新数据库中的数据SQL可从数据库删除记录SQL可创建新数据库SQL可在数据库中创建新表SQL可在数据库中创建存储过程SQL可在数据库中创建视图
SQL可以设置表、存储过程和视图的权限
SQL是一种标准-但是...SQL是一门ANSI的标准计算机语言,用来访问和操作数据库系统。SQL语句用于取回和更新数据库中的数据。SQL可与数据库程序协同工作,比如MSAccess、DB2、Informix、MSSQLServer、Oracle、Sybase以及其他数据库系统。
不幸地是,存在着很多不同版本的SQL语言,但是为了与ANSI标准相兼容,它们必须以相似的方式共同地来支持一些主要的关键词(比如SELECT、UPDATE、DELETE、INSERT、WHERE等等)。
注释:除了SQL标准之外,大部分SQL数据库程序都拥有它们自己的私有扩展!
在您的网站中使用SQL要创建发布数据库中数据的网站,您需要以下要素:
RDBMS数据库程序(比如MSAccess,SQLServer,MySQL)服务器端脚本语言(比如PHP或ASP)SQLHTML/CSS
RDBMSRDBMS指的是关系型数据库管理系统。
RDBMS是SQL的基础,同样也是所有现代数据库系统的基础,比如MSSQLServer,IBMDB2,Oracle,MySQL以及MicrosoftAccess。
RDBMS中的数据存储在被称为表(tables)的数据库对象中。
表是相关的数据项的集合,它由列和行组成。
数据库表一个数据库通常包含一个或多个表。每个表由一个名字标识(例如“客户”或者“订单”)。表包含带有数据的记录(行)。
下面的例子是一个名为\"Persons\"的表:
Id1LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondon2BushGeorgeFifthAvenueNewYork3CarterThomasChanganStreetBeijing上面的表包含三条记录(每一条对应一个人)和五个列(Id、姓、名、地址和城市)。
SQL语句您需要在数据库上执行的大部分工作都由SQL语句完成。
下面的语句从表中选取LastName列的数据:
SELECTLastNameFROMPersons结果集类似这样:
LastNameAdamsBushCarter在本教程中,我们将为您讲解各种不同的SQL语句。
重要事项一定要记住,SQL对大小写不敏感!
SQL语句后面的分号?某些数据库系统要求在每条SQL命令的末端使用分号。在我们的教程中不使用分号。
分号是在数据库系统中分隔每条SQL语句的标准方法,这样就可以在对服务器的相同请求中执行一条以上的语句。
如果您使用的是MSAccess和SQLServer2000,则不必在每条SQL语句之后使用分号,不过某些数据库软件要求必须使用分号。
SQLDML和DDL可以把SQL分为两个部分:数据操作语言(DML)和数据定义语言(DDL)。
SQL(结构化查询语言)是用于执行查询的语法。但是SQL语言也包含用于更新、插入和删除记录的语法。
查询和更新指令构成了SQL的DML部分:
SELECT-从数据库表中获取数据UPDATE-更新数据库表中的数据DELETE-从数据库表中删除数据INSERTINTO-向数据库表中插入数据
SQL的数据定义语言(DDL)部分使我们有能力创建或删除表格。我们也可以定义索引(键),规定表之间的链接,以及施加表间的约束。
SQL中最重要的DDL语句:
CREATEDATABASE-创建新数据库ALTERDATABASE-修改数据库CREATETABLE-创建新表
ALTERTABLE-变更(改变)数据库表DROPTABLE-删除表
CREATEINDEX-创建索引(搜索键)DROPINDEX-删除索引
基础篇
本章讲解SELECT和SELECT*语句。
SQLSELECT语句SELECT语句用于从表中选取数据。
结果被存储在一个结果表中(称为结果集)。
SQLSELECT语法
SELECT列名称FROM表名称以及:
SELECT*FROM表名称注释:SQL语句对大小写不敏感。SELECT等效于select。
SQLSELECT实例如需获取名为\"LastName\"和\"FirstName\"的列的内容(从名为\"Persons\"的数据库表),请使用类似这样的SELECT语句:
SELECTLastName,FirstNameFROMPersons\"Persons\"表:Id1LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondon2BushGeorgeFifthAvenueNewYork3CarterThomasChanganStreetBeijing结果:LastNameAdamsFirstNameJohnBushGeorgeCarterThomasSQLSELECT*实例现在我们希望从\"Persons\"表中选取所有的列。
请使用符号*取代列的名称,就像这样:
SELECT*FROMPersons提示:星号(*)是选取所有列的快捷方式。
结果:Id1LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondon2BushGeorgeFifthAvenueNewYork3CarterThomasChanganStreetBeijing在结果集(result-set)中导航由SQL查询程序获得的结果被存放在一个结果集中。大多数数据库软件系统都允许使用编程函数在结果集中进行导航,比如:Move-To-First-Record、Get-Record-Content、Move-To-Next-Record等等。
类似这些编程函数不在本教程讲解之列。如需学习通过函数调用访问数据的知识,请访问我们的ADO教程和PHP教程。
本章讲解SELECTDISTINCT语句。
SQLSELECTDISTINCT语句在表中,可能会包含重复值。这并不成问题,不过,有时您也许希望仅仅列出不同(distinct)的值。
关键词DISTINCT用于返回唯一不同的值。
语法:
SELECTDISTINCT列名称FROM表名称使用DISTINCT关键词如果要从\"Company\"列中选取所有的值,我们需要使用SELECT语句:
SELECTCompanyFROMOrders\"Orders\"表:CompanyIBMOrderNumber3532W3School2356Apple4698W3School6953结果:CompanyIBMW3SchoolAppleW3School请注意,在结果集中,W3School被列出了两次。
如需从Company\"列中仅选取唯一不同的值,我们需要使用SELECTDISTINCT语句:
SELECTDISTINCTCompanyFROMOrders结果:CompanyIBMW3SchoolApple现在,在结果集中,\"W3School\"仅被列出了一次。
WHERE子句用于规定选择的标准。
WHERE子句如需有条件地从表中选取数据,可将WHERE子句添加到SELECT语句。
语法
SELECT列名称FROM表名称WHERE列运算符值下面的运算符可在WHERE子句中使用:
操作符描述=等于<>不等于>大于<小于>=大于等于<=小于等于BETWEEN在某个范围内LIKE搜索某种模式注释:在某些版本的SQL中,操作符<>可以写为!=。
使用WHERE子句如果只希望选取居住在城市\"Beijing\"中的人,我们需要向SELECT语句添加WHERE子句:
SELECT*FROMPersonsWHERECity='Beijing'\"Persons\"表LastNameFirstNameAddressCityYearAdamsJohnOxfordStreetLondon1970BushGeorgeFifthAvenueNewYork1975CarterThomasChanganStreetBeijing1980GatesBillXuanwumen10Beijing1985结果:LastNameCarterFirstNameThomasAddressChanganStreetCityBeijingYear1980GatesBillXuanwumen10Beijing1985引号的使用请注意,我们在例子中的条件值周围使用的是单引号。
SQL使用单引号来环绕文本值(大部分数据库系统也接受双引号)。如果是数值,请不要使用引号。
文本值:
这是正确的:SELECT*FROMPersonsWHEREFirstName='Bush'这是错误的:SELECT*FROMPersonsWHEREFirstName=Bush数值:
这是正确的:SELECT*FROMPersonsWHEREYear>1965这是错误的:SELECT*FROMPersonsWHEREYear>'1965'SQLAND&OR运算符
AND和OR运算符用于基于一个以上的条件对记录进行过滤。
AND和OR运算符AND和OR可在WHERE子语句中把两个或多个条件结合起来。
如果第一个条件和第二个条件都成立,则AND运算符显示一条记录。
如果第一个条件和第二个条件中只要有一个成立,则OR运算符显示一条记录。
原始的表(用在例子中的):LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondonBushGeorgeFifthAvenueNewYorkCarterThomasChanganStreetBeijingCarterWilliamXuanwumen10BeijingAND运算符实例使用AND来显示所有姓为\"Carter\"并且名为\"Thomas\"的人:
SELECT*FROMPersonsWHEREFirstName='Thomas'ANDLastName='Carter'结果:LastNameCarterFirstNameThomasAddressChanganStreetCityBeijingOR运算符实例使用OR来显示所有姓为\"Carter\"或者名为\"Thomas\"的人:
SELECT*FROMPersonsWHEREfirstname='Thomas'ORlastname='Carter'结果:LastNameCarterFirstNameThomasAddressChanganStreetCityBeijingCarterWilliamXuanwumen10Beijing结合AND和OR运算符我们也可以把AND和OR结合起来(使用圆括号来组成复杂的表达式):
SELECT*FROMPersonsWHERE(FirstName='Thomas'ORFirstName='William')AND结果:
LastName='Carter'LastNameCarterFirstNameThomasAddressChanganStreetCityBeijingCarterWilliamXuanwumen10BeijingSQLORDERBY子句
ORDERBY语句用于对结果集进行排序。
ORDERBY语句ORDERBY语句用于根据指定的列对结果集进行排序。
ORDERBY语句默认按照升序对记录进行排序。
如果您希望按照降序对记录进行排序,可以使用DESC关键字。
原始的表(用在例子中的):Orders表:
CompanyIBMOrderNumber3532W3School2356Apple4698W3School6953实例1以字母顺序显示公司名称:
SELECTCompany,OrderNumberFROMOrdersORDERBYCompany结果:
CompanyAppleOrderNumber4698IBM3532W3School6953W3School2356实例2以字母顺序显示公司名称(Company),并以数字顺序显示顺序号(OrderNumber):
SELECTCompany,OrderNumberFROMOrdersORDERBYCompany,OrderNumber结果:
CompanyAppleOrderNumber4698IBM3532W3School2356W3School6953实例3以逆字母顺序显示公司名称:
SELECTCompany,OrderNumberFROMOrdersORDERBYCompanyDESC结果:CompanyW3SchoolOrderNumber6953W3School2356IBM3532Apple4698实例4以逆字母顺序显示公司名称,并以数字顺序显示顺序号:
SELECTCompany,OrderNumberFROMOrdersASCORDERBYCompanyDESC,OrderNumber结果:CompanyW3SchoolOrderNumber2356W3School6953IBM3532Apple4698注意:在以上的结果中有两个相等的公司名称(W3School)。只有这一次,在第一列中有相同的值时,第二列是以升序排列的。如果第一列中有些值为nulls时,情况也是这样的。
SQLINSERTINTO语句
INSERTINTO语句INSERTINTO语句用于向表格中插入新的行。
语法
INSERTINTO表名称VALUES(值1,值2,....)我们也可以指定所要插入数据的列:
INSERTINTOtable_name(列1,列2,...)VALUES(值1,值2,....)插入新的行\"Persons\"表:LastNameCarterFirstNameThomasAddressChanganStreetCityBeijingSQL语句:
INSERTINTOPersonsVALUES('Gates','Bill','Xuanwumen10','Beijing')结果:LastNameCarterFirstNameThomasAddressChanganStreetCityBeijingGatesBillXuanwumen10Beijing在指定的列中插入数据\"Persons\"表:LastNameCarterFirstNameThomasAddressChanganStreetCityBeijingGatesBillXuanwumen10BeijingSQL语句:
INSERTINTOPersons(LastName,Address)VALUES('Wilson','Champs-Elysees')结果:LastNameCarterFirstNameThomasAddressChanganStreetCityBeijingGatesBillXuanwumen10BeijingWilsonChamps-ElyseesSQLUPDATE语句
Update语句Update语句用于修改表中的数据。
语法:
UPDATE表名称SET列名称=新值WHERE列名称=某值Person:LastNameGatesFirstNameBillAddressXuanwumen10CityBeijingWilsonChamps-Elysees更新某一行中的一个列我们为lastname是\"Wilson\"的人添加firstname:
UPDATEPersonSETFirstName='Fred'WHERELastName='Wilson'结果:LastNameGatesFirstNameBillAddressXuanwumen10CityBeijingWilsonFredChamps-Elysees更新某一行中的若干列我们会修改地址(address),并添加城市名称(city):
UPDATEPersonSETAddress='Zhongshan23',City='Nanjing'WHERELastName='Wilson'结果:
LastNameFirstNameAddressCityGatesBillXuanwumen10BeijingWilsonFredZhongshan23NanjingSQLDELETE语句
DELETE语句DELETE语句用于删除表中的行。
语法
DELETEFROM表名称WHERE列名称=值Person:LastNameGatesFirstNameBillAddressXuanwumen10CityBeijingWilsonFredZhongshan23Nanjing删除某行\"FredWilson\"会被删除:
DELETEFROMPersonWHERELastName='Wilson'结果:LastNameGatesFirstNameBillAddressXuanwumen10CityBeijing删除所有行可以在不删除表的情况下删除所有的行。这意味着表的结构、属性和索引都是完整的:
DELETEFROMtable_name或者:
DELETE*FROMtable_name高级篇
SQLTOP子句
TOP子句TOP子句用于规定要返回的记录的数目。
对于拥有数千条记录的大型表来说,TOP子句是非常有用的。
注释:并非所有的数据库系统都支持TOP子句。
SQLServer的语法:
SELECTTOPnumber|percentcolumn_name(s)FROMtable_nameMySQL和Oracle中的SQLSELECTTOP是等价的MySQL语法
SELECTcolumn_name(s)FROMtable_nameLIMITnumber例子SELECT*FROMPersonsLIMIT5Oracle语法
SELECTcolumn_name(s)FROMtable_nameWHEREROWNUM<=number例子SELECT*FROMPersonsWHEREROWNUM<=5原始的表(用在例子中的):Persons表:
Id1LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondon2BushGeorgeFifthAvenueNewYork3CarterThomasChanganStreetBeijing4ObamaBarackPennsylvaniaAvenueWashingtonSQLTOP实例现在,我们希望从上面的\"Persons\"表中选取头两条记录。
我们可以使用下面的SELECT语句:
SELECTTOP2*FROMPersons结果:Id1LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondon2BushGeorgeFifthAvenueNewYorkSQLTOPPERCENT实例现在,我们希望从上面的\"Persons\"表中选取50%的记录。
我们可以使用下面的SELECT语句:
SELECTTOP50PERCENT*FROMPersons结果:
Id1LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondon2BushGeorgeFifthAvenueNewYorkSQLLIKE操作符
LIKE操作符LIKE操作符用于在WHERE子句中搜索列中的指定模式。
SQLLIKE操作符语法SELECTcolumn_name(s)FROMtable_nameWHEREcolumn_nameLIKEpattern原始的表(用在例子中的):Persons表:
Id1LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondon2BushGeorgeFifthAvenueNewYork3CarterThomasChanganStreetBeijingLIKE操作符实例例子1
现在,我们希望从上面的\"Persons\"表中选取居住在以\"N\"开始的城市里的人:
我们可以使用下面的SELECT语句:
SELECT*FROMPersonsWHERECityLIKE'N%'提示:\"%\"可用于定义通配符(模式中缺少的字母)。
结果集:Id2LastNameBushFirstNameGeorgeAddressFifthAvenueCityNewYork例子2
接下来,我们希望从\"Persons\"表中选取居住在以\"g\"结尾的城市里的人:
我们可以使用下面的SELECT语句:
SELECT*FROMPersonsWHERECityLIKE'%g'结果集:
Id3LastNameCarterFirstNameThomasAddressChanganStreetCityBeijing例子3
接下来,我们希望从\"Persons\"表中选取居住在包含\"lon\"的城市里的人:
我们可以使用下面的SELECT语句:
SELECT*FROMPersonsWHERECityLIKE'%lon%'结果集:Id1LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondon例子4
通过使用NOT关键字,我们可以从\"Persons\"表中选取居住在不包含\"lon\"的城市里的人:
我们可以使用下面的SELECT语句:
SELECT*FROMPersonsWHERECityNOTLIKE'%lon%'结果集:Id2LastNameBushFirstNameGeorgeAddressFifthAvenueCityNewYork3CarterThomasChanganStreetBeijingSQL通配符
在搜索数据库中的数据时,您可以使用SQL通配符。
SQL通配符在搜索数据库中的数据时,SQL通配符可以替代一个或多个字符。
SQL通配符必须与LIKE运算符一起使用。
在SQL中,可使用以下通配符:
通配符描述%替代一个或多个字符_仅替代一个字符[charlist][^charlist]或者[!charlist]字符列中的任何单一字符不在字符列中的任何单一字符原始的表(用在例子中的):Persons表:
Id1LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondon2BushGeorgeFifthAvenueNewYork3CarterThomasChanganStreetBeijing使用%通配符例子1
现在,我们希望从上面的\"Persons\"表中选取居住在以\"Ne\"开始的城市里的人:
我们可以使用下面的SELECT语句:
SELECT*FROMPersonsWHERECityLIKE'Ne%'结果集:Id2LastNameBushFirstNameGeorgeAddressFifthAvenueCityNewYork例子2
接下来,我们希望从\"Persons\"表中选取居住在包含\"lond\"的城市里的人:
我们可以使用下面的SELECT语句:
SELECT*FROMPersonsWHERECityLIKE'%lond%'结果集:Id1LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondon使用_通配符例子1
现在,我们希望从上面的\"Persons\"表中选取名字的第一个字符之后是\"eorge\"的人:
我们可以使用下面的SELECT语句:
SELECT*FROMPersonsWHEREFirstNameLIKE'_eorge'结果集:Id2LastNameBushFirstNameGeorgeAddressFifthAvenueCityNewYork例子2
接下来,我们希望从\"Persons\"表中选取的这条记录的姓氏以\"C\"开头,然后是一个任意字符,然后是\"r\",然后是任意字符,然后是\"er\":
我们可以使用下面的SELECT语句:
SELECT*FROMPersonsWHERELastNameLIKE'C_r_er'结果集:
Id3LastNameCarterFirstNameThomasAddressChanganStreetCityBeijing使用[charlist]通配符例子1
现在,我们希望从上面的\"Persons\"表中选取居住的城市以\"A\"或\"L\"或\"N\"开头的人:
我们可以使用下面的SELECT语句:
SELECT*FROMPersonsWHERECityLIKE'[ALN]%'结果集:Id1LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondon2BushGeorgeFifthAvenueNewYork例子2
现在,我们希望从上面的\"Persons\"表中选取居住的城市不以\"A\"或\"L\"或\"N\"开头的人:
我们可以使用下面的SELECT语句:
SELECT*FROMPersonsWHERECityLIKE'[!ALN]%'结果集:Id3LastNameCarterFirstNameThomasAddressChanganStreetCityBeijingSQLIN操作符
IN操作符IN操作符允许我们在WHERE子句中规定多个值。
SQLIN语法
SELECTcolumn_name(s)FROMtable_nameWHEREcolumn_nameIN(value1,value2,...)原始的表(在实例中使用:)Persons表:
Id1LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondon2BushGeorgeFifthAvenueNewYork3CarterThomasChanganStreetBeijingIN操作符实例现在,我们希望从上表中选取姓氏为Adams和Carter的人:
我们可以使用下面的SELECT语句:
SELECT*FROMPersonsWHERELastNameIN('Adams','Carter')结果集:Id1LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondon3CarterThomasChanganStreetBeijingSQLBETWEEN操作符
BETWEEN操作符在WHERE子句中使用,作用是选取介于两个值之间的数据范围。
BETWEEN操作符操作符BETWEEN...AND会选取介于两个值之间的数据范围。这些值可以是数值、文本或者日期。
SQLBETWEEN语法
SELECTcolumn_name(s)FROMtable_nameWHEREcolumn_nameBETWEENvalue1ANDvalue2原始的表(在实例中使用:)Persons表:
Id1LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondon2BushGeorgeFifthAvenueNewYork3CarterThomasChanganStreetBeijing4GatesBillXuanwumen10BeijingBETWEEN操作符实例如需以字母顺序显示介于\"Adams\"(包括)和\"Carter\"(不包括)之间的人,请使用下面的SQL:
SELECT*FROMPersonsWHERELastNameBETWEEN结果集:Id1'Adams'AND'Carter'LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondon2BushGeorgeFifthAvenueNewYork重要事项:不同的数据库对BETWEEN...AND操作符的处理方式是有差异的。某些数据库会列出介于\"Adams\"和\"Carter\"之间的人,但不包括\"Adams\"和\"Carter\";某些数据库会列出介于\"Adams\"和\"Carter\"之间并包括\"Adams\"和\"Carter\"的人;而另一些数据库会列出介于\"Adams\"和\"Carter\"之间的人,包括\"Adams\",但不包括\"Carter\"。
所以,请检查你的数据库是如何处理BETWEEN....AND操作符的!
实例2如需使用上面的例子显示范围之外的人,请使用NOT操作符:
SELECT*FROMPersonsWHERELastNameNOTBETWEEN'Adams'AND'Carter'结果集:Id3LastNameCarterFirstNameThomasAddressChanganStreetCityBeijing4GatesBillXuanwumen10BeijingSQLAlias(别名)
通过使用SQL,可以为列名称和表名称指定别名(Alias)。
SQLAlias表的SQLAlias语法SELECTcolumn_name(s)FROMtable_nameASalias_name列的SQLAlias语法
SELECTcolumn_nameASalias_nameFROMtable_nameAlias实例:使用表名称别名假设我们有两个表分别是:\"Persons\"和\"Product_Orders\"。我们分别为它们指定别名\"p\"和\"po\"。
现在,我们希望列出\"JohnAdams\"的所有定单。
我们可以使用下面的SELECT语句:
SELECTpo.OrderID,p.LastName,p.FirstNameFROMPersonsASp,Product_OrdersASpoWHEREp.LastName='Adams'ANDp.FirstName='John'不使用别名的SELECT语句:
SELECTProduct_Orders.OrderID,Persons.LastName,Persons.FirstNameFROMPersons,Product_OrdersWHEREPersons.LastName='Adams'ANDPersons.FirstName='John'从上面两条SELECT语句您可以看到,别名使查询程序更易阅读和书写。
Alias实例:使用一个列名别名表Persons:Id1LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondon2BushGeorgeFifthAvenueNewYork3CarterThomasChanganStreetBeijingSQL:
SELECTLastNameFROMPersonsASFamily,FirstNameASName结果:FamilyAdamsNameJohnBushGeorgeCarterThomasSQLJOIN
SQLjoin用于根据两个或多个表中的列之间的关系,从这些表中查询数据。
Join和Key有时为了得到完整的结果,我们需要从两个或更多的表中获取结果。我们就需要执行join。
数据库中的表可通过键将彼此联系起来。主键(PrimaryKey)是一个列,在这个列中的每一行的值都是唯一的。在表中,每个主键的值都是唯一的。这样做的目的是在不重复每个表中的所有数据的情况下,把表间的数据交叉捆绑在一起。
请看\"Persons\"表:
Id_P1LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondon2BushGeorgeFifthAvenueNewYork3CarterThomasChanganStreetBeijing请注意,\"Id_P\"列是Persons表中的的主键。这意味着没有两行能够拥有相同的Id_P。即使两个人的姓名完全相同,Id_P也可以区分他们。
接下来请看\"Orders\"表:
Id_O1OrderNo775Id_P3244678332245614245621534765请注意,\"Id_O\"列是Orders表中的的主键,同时,\"Orders\"表中的\"Id_P\"列用于引用\"Persons\"表中的人,而无需使用他们的确切姓名。
请留意,\"Id_P\"列把上面的两个表联系了起来。
引用两个表我们可以通过引用两个表的方式,从两个表中获取数据:
谁订购了产品,并且他们订购了什么产品?
SELECTPersons.LastName,Persons.FirstName,Orders.OrderNoFROMPersons,OrdersWHEREPersons.Id_P=Orders.Id_P结果集:
LastNameAdamsFirstNameJohnOrderNo22456AdamsJohn24562CarterThomas775CarterThomas44678SQLJOIN-使用Join除了上面的方法,我们也可以使用关键词JOIN来从两个表中获取数据。
如果我们希望列出所有人的定购,可以使用下面的SELECT语句:
SELECTPersons.LastName,Persons.FirstName,Orders.OrderNoFROMPersonsINNERJOINOrdersONPersons.Id_P=Orders.Id_PORDERBYPersons.LastName结果集:
LastNameAdamsFirstNameJohnOrderNo22456AdamsJohn24562CarterThomas775CarterThomas44678不同的SQLJOIN除了我们在上面的例子中使用的INNERJOIN(内连接),我们还可以使用其他几种连接。
下面列出了您可以使用的JOIN类型,以及它们之间的差异。
JOIN:如果表中有至少一个匹配,则返回行
LEFTJOIN:即使右表中没有匹配,也从左表返回所有的行RIGHTJOIN:即使左表中没有匹配,也从右表返回所有的行FULLJOIN:只要其中一个表中存在匹配,就返回行
SQLINNERJOIN关键字
SQLINNERJOIN关键字在表中存在至少一个匹配时,INNERJOIN关键字返回行。
INNERJOIN关键字语法SELECTcolumn_name(s)FROMtable_name1INNERJOINtable_name2ONtable_name1.column_name=table_name2.column_name注释:INNERJOIN与JOIN是相同的。
原始的表(用在例子中的):\"Persons\"表:
Id_P1LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondon2BushGeorgeFifthAvenueNewYork3CarterThomasChanganStreetBeijing\"Orders\"表:
Id_O1OrderNo775Id_P3244678332245614245621534765内连接(INNERJOIN)实例现在,我们希望列出所有人的定购。
您可以使用下面的SELECT语句:
SELECTPersons.LastName,Persons.FirstName,Orders.OrderNoFROMPersonsINNERJOINOrdersONPersons.Id_P=Orders.Id_PORDERBYPersons.LastName结果集:
LastNameAdamsFirstNameJohnOrderNo22456AdamsJohn24562CarterThomas775CarterThomas44678INNERJOIN关键字在表中存在至少一个匹配时返回行。如果\"Persons\"中的行在\"Orders\"中没有匹配,就不会列出这些行。
SQLLEFTJOIN关键字
SQLLEFTJOIN关键字LEFTJOIN关键字会从左表(table_name1)那里返回所有的行,即使在右表(table_name2)中没有匹配的行。
LEFTJOIN关键字语法SELECTcolumn_name(s)FROMtable_name1LEFTJOINtable_name2ONtable_name1.column_name=table_name2.column_name注释:在某些数据库中,LEFTJOIN称为LEFTOUTERJOIN。
原始的表(用在例子中的):\"Persons\"表:
Id_P1LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondon2BushGeorgeFifthAvenueNewYork3CarterThomasChanganStreetBeijing\"Orders\"表:
Id_O1OrderNo775Id_P3244678332245614245621534765左连接(LEFTJOIN)实例现在,我们希望列出所有的人,以及他们的定购-如果有的话。
您可以使用下面的SELECT语句:
SELECTPersons.LastName,Persons.FirstName,Orders.OrderNoFROMPersonsLEFTJOINOrdersONPersons.Id_P=Orders.Id_PORDERBYPersons.LastName结果集:
LastNameAdamsFirstNameJohnOrderNo22456AdamsJohn24562CarterThomas775CarterThomas44678BushGeorgeLEFTJOIN关键字会从左表(Persons)那里返回所有的行,即使在右表(Orders)中没有匹配的行。
SQLRIGHTJOIN关键字
SQLRIGHTJOIN关键字RIGHTJOIN关键字会右表(table_name2)那里返回所有的行,即使在左表(table_name1)中没有匹配的行。
RIGHTJOIN关键字语法SELECTcolumn_name(s)FROMtable_name1RIGHTJOINtable_name2ONtable_name1.column_name=table_name2.column_name注释:在某些数据库中,RIGHTJOIN称为RIGHTOUTERJOIN。
原始的表(用在例子中的):\"Persons\"表:
Id_P1LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondon2BushGeorgeFifthAvenueNewYork3CarterThomasChanganStreetBeijing\"Orders\"表:
Id_O1OrderNo775Id_P3244678332245614245621534765右连接(RIGHTJOIN)实例现在,我们希望列出所有的定单,以及定购它们的人-如果有的话。
您可以使用下面的SELECT语句:
SELECTPersons.LastName,Persons.FirstName,Orders.OrderNoFROMPersonsRIGHTJOINOrdersONPersons.Id_P=Orders.Id_PORDERBYPersons.LastName结果集:
LastNameAdamsFirstNameJohnOrderNo22456AdamsJohn24562CarterThomas775CarterThomas44678347RIGHTJOIN关键字会从右表(Orders)那里返回所有的行,即使在左表(Persons)中没有匹配的行。
SQLFULLJOIN关键字
SQLFULLJOIN关键字只要其中某个表存在匹配,FULLJOIN关键字就会返回行。
FULLJOIN关键字语法SELECTcolumn_name(s)FROMtable_name1FULLJOINtable_name2ONtable_name1.column_name=table_name2.column_name注释:在某些数据库中,FULLJOIN称为FULLOUTERJOIN。
原始的表(用在例子中的):\"Persons\"表:
Id_P1LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondon2BushGeorgeFifthAvenueNewYork3CarterThomasChanganStreetBeijing\"Orders\"表:
Id_O1OrderNo775Id_P3244678332245614245621534765全连接(FULLJOIN)实例现在,我们希望列出所有的人,以及他们的定单,以及所有的定单,以及定购它们的人。
您可以使用下面的SELECT语句:
SELECTPersons.LastName,Persons.FirstName,Orders.OrderNoFROMPersonsFULLJOINOrdersONPersons.Id_P=Orders.Id_PORDERBYPersons.LastName结果集:
LastNameAdamsFirstNameJohnOrderNo22456AdamsJohn24562CarterThomas775CarterThomas44678BushGeorge347FULLJOIN关键字会从左表(Persons)和右表(Orders)那里返回所有的行。如果\"Persons\"中的行在表\"Orders\"中没有匹配,或者如果\"Orders\"中的行在表\"Persons\"中没有匹配,这些行同样会列出。
SQLUNION和UNIONALL操作符
SQLUNION操作符UNION操作符用于合并两个或多个SELECT语句的结果集。
请注意,UNION内部的SELECT语句必须拥有相同数量的列。列也必须拥有相似的数据类型。同时,每条SELECT语句中的列的顺序必须相同。
SQLUNION语法
SELECTcolumn_name(s)FROMtable_name1UNIONSELECTcolumn_name(s)FROMtable_name2注释:默认地,UNION操作符选取不同的值。如果允许重复的值,请使用UNIONALL。
SQLUNIONALL语法
SELECTcolumn_name(s)FROMtable_name1UNIONALLSELECTcolumn_name(s)FROMtable_name2另外,UNION结果集中的列名总是等于UNION中第一个SELECT语句中的列名。
下面的例子中使用的原始表:Employees_China:E_ID01E_NameZhang,Hua02Wang,Wei03Carter,Thomas04Yang,MingEmployees_USA:E_ID01E_NameAdams,John02Bush,George03Carter,Thomas04Gates,Bill使用UNION命令实例
列出所有在中国和美国的不同的雇员名:
SELECTE_NameFROMEmployees_ChinaUNIONSELECTE_NameFROMEmployees_USA结果E_NameZhang,HuaWang,WeiCarter,ThomasYang,MingAdams,JohnBush,GeorgeGates,Bill注释:这个命令无法列出在中国和美国的所有雇员。在上面的例子中,我们有两个名字相同的雇员,他们当中只有一个人被列出来了。UNION命令只会选取不同的值。
UNIONALLUNIONALL命令和UNION命令几乎是等效的,不过UNIONALL命令会列出所有的值。
SQLStatement1UNIONALLSQLStatement2使用UNIONALL命令实例:
列出在中国和美国的所有的雇员:
SELECTE_NameFROMEmployees_ChinaUNIONALLSELECTE_NameFROMEmployees_USA结果
E_NameZhang,HuaWang,WeiCarter,ThomasYang,MingAdams,JohnBush,GeorgeCarter,ThomasGates,BillSQLSELECTINTO语句
SQLSELECTINTO语句可用于创建表的备份复件。
SELECTINTO语句SELECTINTO语句从一个表中选取数据,然后把数据插入另一个表中。
SELECTINTO语句常用于创建表的备份复件或者用于对记录进行存档。
SQLSELECTINTO语法您可以把所有的列插入新表:
SELECT*INTOnew_table_name[INexternaldatabase]FROMold_tablename或者只把希望的列插入新表:
SELECTcolumn_name(s)INTOnew_table_name[INexternaldatabase]FROMold_tablenameSQLSELECTINTO实例-制作备份复件下面的例子会制作\"Persons\"表的备份复件:
SELECTINTO*Persons_backupFROMPersonsIN子句可用于向另一个数据库中拷贝表:
SELECTINTO*PersonsIN'Backup.mdb'FROMPersons如果我们希望拷贝某些域,可以在SELECT语句后列出这些域:
SELECTINTOLastName,FirstNamePersons_backupFROMPersonsSQLSELECTINTO实例-带有WHERE子句我们也可以添加WHERE子句。
下面的例子通过从\"Persons\"表中提取居住在\"Beijing\"的人的信息,创建了一个带有两个列的名为\"Persons_backup\"的表:
SELECTINTOLastName,FirstnamePersons_backupFROMPersonsWHERECity='Beijing'SQLSELECTINTO实例-被连接的表从一个以上的表中选取数据也是可以做到的。
下面的例子会创建一个名为\"Persons_Order_Backup\"的新表,其中包含了从Persons和Orders两个表中取得的信息:
SELECTPersons.LastName,Orders.OrderNoINTOFROMONPersons_Order_BackupPersonsOrdersINNERJOINPersons.Id_P=Orders.Id_PSQLCREATEDATABASE语句
CREATEDATABASE语句CREATEDATABASE用于创建数据库。
SQLCREATEDATABASE语法CREATEDATABASEdatabase_nameSQLCREATEDATABASE实例现在我们希望创建一个名为\"my_db\"的数据库。
我们使用下面的CREATEDATABASE语句:
CREATEDATABASEmy_db可以通过CREATETABLE来添加数据库表。
SQLCREATETABLE语句
CREATETABLE语句CREATETABLE语句用于创建数据库中的表。
SQLCREATETABLE语法CREATETABLE表名称(列名称1数据类型,列名称2数据类型,列名称3数据类型,....)数据类型(data_type)规定了列可容纳何种数据类型。下面的表格包含了SQL中最常用的数据类型:
数据类型描述仅容纳整数。在括号内规定数字的最大位数。integer(size)int(size)smallint(size)tinyint(size)decimal(size,d)numeric(size,d)容纳带有小数的数字。\"size\"规定数字的最大位数。\"d\"规定小数点右侧的最大位数。char(size)容纳固定长度的字符串(可容纳字母、数字以及特殊字符)。在括号中规定字符串的长度。varchar(size)容纳可变长度的字符串(可容纳字母、数字以及特殊的字符)。在括号中规定字符串的最大长度。date(yyyymmdd)容纳日期。SQLCREATETABLE实例本例演示如何创建名为\"Person\"的表。
该表包含5个列,列名分别是:\"Id_P\"、\"LastName\"、\"FirstName\"、\"Address\"以及\"City\":
CREATETABLEPersons(Id_Pint,LastNamevarchar(255),FirstNamevarchar(255),Addressvarchar(255),Cityvarchar(255))Id_P列的数据类型是int,包含整数。其余4列的数据类型是varchar,最大长度为255个字符。
空的\"Persons\"表类似这样:
Id_PLastNameFirstNameAddressCity可使用INSERTINTO语句向空表写入数据。
SQL约束(Constraints)
SQL约束约束用于加入表的数据的类型。
可以在创建表时规定约束(通过CREATETABLE语句),或者在表创建之后也可以(通过ALTERTABLE语句)。
我们将主要探讨以下几种约束:
NOTNULLUNIQUEPRIMARYKEYFOREIGNKEYCHECKDEFAULT
注释:在下面的章节,我们会详细讲解每一种约束。
SQLNOTNULL约束
SQLNOTNULL约束NOTNULL约束强制列不接受NULL值。
NOTNULL约束强制字段始终包含值。这意味着,如果不向字段添加值,就无法插入新纪录或者更新记录。
下面的SQL语句强制\"Id_P\"列和\"LastName\"列不接受NULL值:
CREATETABLEPersons(Id_PintNOTNULL,NOTNULL,LastNamevarchar(255)FirstNamevarchar(255),Addressvarchar(255),Cityvarchar(255))SQLUNIQUE约束
SQLUNIQUE约束UNIQUE约束唯一标识数据库表中的每条记录。
UNIQUE和PRIMARYKEY约束均为列或列集合提供了唯一性的保证。
PRIMARYKEY拥有自动定义的UNIQUE约束。
请注意,每个表可以有多个UNIQUE约束,但是每个表只能有一个PRIMARYKEY约束。
SQLUNIQUEConstraintonCREATETABLE下面的SQL在\"Persons\"表创建时在\"Id_P\"列创建UNIQUE约束:
MySQL:
CREATETABLEPersons(Id_PintNOTNULL,LastNamevarchar(255)NOTNULL,FirstNamevarchar(255),Addressvarchar(255),Cityvarchar(255),UNIQUE(Id_P))SQLServer/Oracle/MSAccess:CREATETABLEPersons(Id_PintNOTNULLUNIQUE,LastNamevarchar(255)NOTNULL,FirstNamevarchar(255),Addressvarchar(255),Cityvarchar(255))如果需要命名UNIQUE约束,以及为多个列定义UNIQUE约束,请使用下面的SQL语法:
MySQL/SQLServer/Oracle/MSAccess:CREATETABLEPersons(Id_PintNOTNULL,LastNamevarchar(255)NOTNULL,FirstNamevarchar(255),Addressvarchar(255),Cityvarchar(255),CONSTRAINTuc_PersonIDUNIQUE(Id_P,LastName))SQLUNIQUEConstraintonALTERTABLE当表已被创建时,如需在\"P_Id\"列创建UNIQUE约束,请使用下列SQL:
MySQL/SQLServer/Oracle/MSAccess:ALTERTABLEPersonsADDUNIQUE(P_Id)如需命名UNIQUE约束,并定义多个列的UNIQUE约束,请使用下面的SQL语法:
MySQL/SQLServer/Oracle/MSAccess:ALTERTABLEPersonsADDCONSTRAINTuc_PersonIDUNIQUE(P_Id,LastName)撤销UNIQUE约束如需撤销UNIQUE约束,请使用下面的SQL:
MySQL:
ALTERTABLEPersonsDROPINDEXuc_PersonIDSQLServer/Oracle/MSAccess:ALTERTABLEPersonsDROPCONSTRAINTuc_PersonIDSQLPRIMARYKEY约束
SQLPRIMARYKEY约束PRIMARYKEY约束唯一标识数据库表中的每条记录。
主键必须包含唯一的值。
主键列不能包含NULL值。
每个表都应该有一个主键,并且每个表只能有一个主键。
SQLPRIMARYKEYConstraintonCREATETABLE下面的SQL在\"Persons\"表创建时在\"Id_P\"列创建PRIMARYKEY约束:
MySQL:
CREATETABLEPersons(Id_PintNOTNULL,LastNamevarchar(255)NOTNULL,FirstNamevarchar(255),Addressvarchar(255),Cityvarchar(255),PRIMARYKEY(Id_P))SQLServer/Oracle/MSAccess:
CREATETABLEPersons(Id_PintNOTNULLPRIMARYKEY,LastNamevarchar(255)NOTNULL,FirstNamevarchar(255),Addressvarchar(255),Cityvarchar(255))如果需要命名PRIMARYKEY约束,以及为多个列定义PRIMARYKEY约束,请使用下面的SQL语法:
MySQL/SQLServer/Oracle/MSAccess:CREATETABLEPersons(Id_PintNOTNULL,LastNamevarchar(255)NOTNULL,FirstNamevarchar(255),Addressvarchar(255),Cityvarchar(255),CONSTRAINTuc_PersonIDPRIMARYKEY(Id_P,LastName))SQLPRIMARYKEYConstraintonALTERTABLE如果在表已存在的情况下为\"Id_P\"列创建PRIMARYKEY约束,请使用下面的SQL:
MySQL/SQLServer/Oracle/MSAccess:ALTERTABLEPersonsADDPRIMARYKEY(Id_P)如果需要命名PRIMARYKEY约束,以及为多个列定义PRIMARYKEY约束,请使用下面的SQL语法:
MySQL/SQLServer/Oracle/MSAccess:ALTERTABLEPersonsADDCONSTRAINTpk_PersonIDPRIMARYKEY(Id_P,LastName)注释:如果您使用ALTERTABLE语句添加主键,必须把主键列声明为不包含NULL值(在表首次创建时)。
撤销PRIMARYKEY约束如需撤销PRIMARYKEY约束,请使用下面的SQL:
MySQL:
ALTERTABLEPersonsDROPPRIMARYKEYSQLServer/Oracle/MSAccess:ALTERTABLEPersonsDROPCONSTRAINTpk_PersonIDSQLFOREIGNKEY约束
SQLFOREIGNKEY约束一个表中的FOREIGNKEY指向另一个表中的PRIMARYKEY。
让我们通过一个例子来解释外键。请看下面两个表:
\"Persons\"表:
Id_P1LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondon2BushGeorgeFifthAvenueNewYork3CarterThomasChanganStreetBeijing\"Orders\"表:
Id_O1OrderNo775Id_P3244678332245614245621请注意,\"Orders\"中的\"Id_P\"列指向\"Persons\"表中的\"Id_P\"列。
\"Persons\"表中的\"Id_P\"列是\"Persons\"表中的PRIMARYKEY。
\"Orders\"表中的\"Id_P\"列是\"Orders\"表中的FOREIGNKEY。
FOREIGNKEY约束用于预防破坏表之间连接的动作。
FOREIGNKEY约束也能防止非法数据插入外键列,因为它必须是它指向的那个表中的值之一。
SQLFOREIGNKEYConstraintonCREATETABLE下面的SQL在\"Orders\"表创建时为\"Id_P\"列创建FOREIGNKEY:
MySQL:
CREATETABLEOrders(O_IdintNOTNULL,OrderNointNOTNULL,Id_Pint,PRIMARYKEY(O_Id),FOREIGNKEY(Id_P)REFERENCESPersons(Id_P))SQLServer/Oracle/MSAccess:CREATETABLEOrders(O_IdintNOTNULLPRIMARYKEY,OrderNointNOTNULL,Id_PintFOREIGNKEYREFERENCESPersons(Id_P))如果需要命名FOREIGNKEY约束,以及为多个列定义FOREIGNKEY约束,请使用下面的SQL语法:
MySQL/SQLServer/Oracle/MSAccess:CREATETABLEOrders(O_IdintNOTNULL,OrderNointNOTNULL,Id_Pint,PRIMARYKEY(O_Id),CONSTRAINTfk_PerOrdersFOREIGNKEY(Id_P)REFERENCESPersons(Id_P))SQLFOREIGNKEYConstraintonALTERTABLE如果在\"Orders\"表已存在的情况下为\"Id_P\"列创建FOREIGNKEY约束,请使用下面的SQL:
MySQL/SQLServer/Oracle/MSAccess:ALTERTABLEOrdersADDFOREIGNKEY(Id_P)REFERENCESPersons(Id_P)如果需要命名FOREIGNKEY约束,以及为多个列定义FOREIGNKEY约束,请使用下面的SQL语法:
MySQL/SQLServer/Oracle/MSAccess:ALTERTABLEOrdersADDCONSTRAINTfk_PerOrdersFOREIGNKEY(Id_P)REFERENCESPersons(Id_P)撤销FOREIGNKEY约束如需撤销FOREIGNKEY约束,请使用下面的SQL:
MySQL:
ALTERTABLEOrdersDROPFOREIGNKEYfk_PerOrdersSQLServer/Oracle/MSAccess:ALTERTABLEOrdersDROPCONSTRAINTfk_PerOrdersSQLCHECK约束
CHECK约束用于列中的值的范围。
如果对单个列定义CHECK约束,那么该列只允许特定的值。
如果对一个表定义CHECK约束,那么此约束会在特定的列中对值进行。
SQLCHECKConstraintonCREATETABLE下面的SQL在\"Persons\"表创建时为\"Id_P\"列创建CHECK约束。CHECK约束规定\"Id_P\"列必须只包含大于0的整数。
MySQL:
CREATETABLEPersons(Id_PintNOTNULL,LastNamevarchar(255)NOTNULL,FirstNamevarchar(255),Addressvarchar(255),Cityvarchar(255),CHECK(Id_P>0))SQLServer/Oracle/MSAccess:CREATETABLEPersons(Id_PintNOTNULLCHECK(Id_P>0),LastNamevarchar(255)NOTNULL,FirstNamevarchar(255),Addressvarchar(255),Cityvarchar(255))如果需要命名CHECK约束,以及为多个列定义CHECK约束,请使用下面的SQL语法:
MySQL/SQLServer/Oracle/MSAccess:CREATETABLEPersons(Id_PintNOTNULL,LastNamevarchar(255)NOTNULL,FirstNamevarchar(255),Addressvarchar(255),Cityvarchar(255),CONSTRAINTchk_PersonCHECK(Id_P>0ANDCity='Sandnes'))SQLCHECKConstraintonALTERTABLE如果在表已存在的情况下为\"Id_P\"列创建CHECK约束,请使用下面的SQL:
MySQL/SQLServer/Oracle/MSAccess:ALTERTABLEPersonsADDCHECK(Id_P>0)如果需要命名CHECK约束,以及为多个列定义CHECK约束,请使用下面的SQL语法:
MySQL/SQLServer/Oracle/MSAccess:ALTERTABLEPersonsADDCONSTRAINTchk_PersonCHECK(Id_P>0ANDCity='Sandnes')撤销CHECK约束如需撤销CHECK约束,请使用下面的SQL:
SQLServer/Oracle/MSAccess:ALTERTABLEPersonsDROPCONSTRAINTchk_PersonSQLDEFAULT约束
SQLDEFAULT约束DEFAULT约束用于向列中插入默认值。
如果没有规定其他的值,那么会将默认值添加到所有的新纪录。
SQLDEFAULTConstraintonCREATETABLE下面的SQL在\"Persons\"表创建时为\"City\"列创建DEFAULT约束:
MySQL/SQLServer/Oracle/MSAccess:CREATETABLEPersons(Id_PintNOTNULL,LastNamevarchar(255)NOTNULL,FirstNamevarchar(255),Addressvarchar(255),Cityvarchar(255)DEFAULT'Sandnes')通过使用类似GETDATE()这样的函数,DEFAULT约束也可以用于插入系统值:
CREATETABLEOrders(Id_OintNOTNULL,OrderNointNOTNULL,Id_Pint,OrderDatedateDEFAULTGETDATE())SQLDEFAULTConstraintonALTERTABLE如果在表已存在的情况下为\"City\"列创建DEFAULT约束,请使用下面的SQL:
MySQL:
ALTERTABLEPersonsALTERCitySETDEFAULT'SANDNES'SQLServer/Oracle/MSAccess:ALTERTABLEPersonsALTERCOLUMNCitySETDEFAULT'SANDNES'撤销DEFAULT约束如需撤销DEFAULT约束,请使用下面的SQL:
MySQL:
ALTERTABLEPersonsALTERCityDROPDEFAULTSQLServer/Oracle/MSAccess:ALTERTABLEPersonsALTERCOLUMNCityDROPDEFAULTSQLCREATEINDEX语句
CREATEINDEX语句用于在表中创建索引。
在不读取整个表的情况下,索引使数据库应用程序可以更快地查找数据。
索引您可以在表中创建索引,以便更加快速高效地查询数据。
用户无法看到索引,它们只能被用来加速搜索/查询。
注释:更新一个包含索引的表需要比更新一个没有索引的表更多的时间,这是由于索引本身也需要更新。因此,理想的做法是仅仅在常常被搜索的列(以及表)上面创建索引。
SQLCREATEINDEX语法
在表上创建一个简单的索引。允许使用重复的值:
CREATEINDEXindex_nameONtable_name(column_name)注释:\"column_name\"规定需要索引的列。
SQLCREATEUNIQUEINDEX语法
在表上创建一个唯一的索引。唯一的索引意味着两个行不能拥有相同的索引值。
CREATEUNIQUEINDEXindex_nameONtable_name(column_name)CREATEINDEX实例本例会创建一个简单的索引,名为\"PersonIndex\",在Person表的LastName列:
CREATEINDEXPersonIndexONPerson(LastName)如果您希望以降序索引某个列中的值,您可以在列名称之后添加保留字DESC:
CREATEINDEXPersonIndexONPerson(LastNameDESC)假如您希望索引不止一个列,您可以在括号中列出这些列的名称,用逗号隔开:
CREATEINDEXPersonIndexONPerson(LastName,FirstName)SQL撤销索引、表以及数据库
通过使用DROP语句,可以轻松地删除索引、表和数据库。
SQLDROPINDEX语句我们可以使用DROPINDEX命令删除表格中的索引。
用于MicrosoftSQLJet(以及MicrosoftAccess)的语法:DROPINDEXindex_nameONtable_name用于MSSQLServer的语法:
DROPINDEXtable_name.index_name用于IBMDB2和Oracle语法:DROPINDEXindex_name用于MySQL的语法:
ALTERTABLEtable_nameDROPINDEXindex_nameSQLDROPTABLE语句DROPTABLE语句用于删除表(表的结构、属性以及索引也会被删除):
DROPTABLE表名称SQLDROPDATABASE语句DROPDATABASE语句用于删除数据库:
DROPDATABASE数据库名称SQLTRUNCATETABLE语句如果我们仅仅需要除去表内的数据,但并不删除表本身,那么我们该如何做呢?
请使用TRUNCATETABLE命令(仅仅删除表格中的数据):
TRUNCATETABLE表名称SQLALTERTABLE语句
ALTERTABLE语句ALTERTABLE语句用于在已有的表中添加、修改或删除列。
SQLALTERTABLE语法如需在表中添加列,请使用下列语法:
ALTERTABLEtable_nameADDcolumn_namedatatype要删除表中的列,请使用下列语法:
ALTERTABLEtable_nameDROPCOLUMNcolumn_name注释:某些数据库系统不允许这种在数据库表中删除列的方式(DROPCOLUMNcolumn_name)。
要改变表中列的数据类型,请使用下列语法:
ALTERTABLEtable_nameALTERCOLUMNcolumn_namedatatype原始的表(用在例子中的):Persons表:
Id1LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondon2BushGeorgeFifthAvenueNewYork3CarterThomasChanganStreetBeijingSQLALTERTABLE实例现在,我们希望在表\"Persons\"中添加一个名为\"Birthday\"的新列。
我们使用下列SQL语句:
ALTERTABLEPersonsADDBirthdaydate请注意,新列\"Birthday\"的类型是date,可以存放日期。数据类型规定列中可以存放的数据的类型。
新的\"Persons\"表类似这样:
Id1LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondonBirthday2BushGeorgeFifthAvenueNewYork3CarterThomasChanganStreetBeijing改变数据类型实例现在我们希望改变\"Persons\"表中\"Birthday\"列的数据类型。
我们使用下列SQL语句:
ALTERTABLEPersonsALTERCOLUMNBirthdayyear请注意,\"Birthday\"列的数据类型是year,可以存放2位或4位格式的年份。
DROPCOLUMN实例接下来,我们删除\"Person\"表中的\"Birthday\"列:
ALTERTABLEPersonDROPCOLUMNBirthdayPersons表会成为这样:
Id1LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondon2BushGeorgeFifthAvenueNewYork3CarterThomasChanganStreetBeijingSQLAUTOINCREMENT字段
Auto-increment会在新纪录插入表中时生成一个唯一的数字。
AUTOINCREMENT字段我们通常希望在每次插入新纪录时,自动地创建主键字段的值。
我们可以在表中创建一个auto-increment字段。
用于MySQL的语法下列SQL语句把\"Persons\"表中的\"P_Id\"列定义为auto-increment主键:
CREATETABLEPersons(P_IdintNOTNULLAUTO_INCREMENT,LastNamevarchar(255)NOTNULL,FirstNamevarchar(255),Addressvarchar(255),Cityvarchar(255),PRIMARYKEY(P_Id))MySQL使用AUTO_INCREMENT关键字来执行auto-increment任务。
默认地,AUTO_INCREMENT的开始值是1,每条新纪录递增1。
要让AUTO_INCREMENT序列以其他的值起始,请使用下列SQL语法:
ALTERTABLEPersonsAUTO_INCREMENT=100要在\"Persons\"表中插入新纪录,我们不必为\"P_Id\"列规定值(会自动添加一个唯一的值):
INSERTINTOPersons(FirstName,LastName)VALUES('Bill','Gates')上面的SQL语句会在\"Persons\"表中插入一条新纪录。\"P_Id\"会被赋予一个唯一的值。\"FirstName\"会被设置为\"Bill\",\"LastName\"列会被设置为\"Gates\"。
用于SQLServer的语法下列SQL语句把\"Persons\"表中的\"P_Id\"列定义为auto-increment主键:
CREATETABLEPersons(P_IdintPRIMARYKEYIDENTITY,LastNamevarchar(255)NOTNULL,FirstNamevarchar(255),Addressvarchar(255),Cityvarchar(255))MSSQL使用IDENTITY关键字来执行auto-increment任务。
默认地,IDENTITY的开始值是1,每条新纪录递增1。
要规定\"P_Id\"列以20起始且递增10,请把identity改为IDENTITY(20,10)
要在\"Persons\"表中插入新纪录,我们不必为\"P_Id\"列规定值(会自动添加一个唯一的值):
INSERTINTOPersons(FirstName,LastName)VALUES('Bill','Gates')上面的SQL语句会在\"Persons\"表中插入一条新纪录。\"P_Id\"会被赋予一个唯一的值。\"FirstName\"会被设置为\"Bill\",\"LastName\"列会被设置为\"Gates\"。
用于Access的语法下列SQL语句把\"Persons\"表中的\"P_Id\"列定义为auto-increment主键:
CREATETABLEPersons(P_IdintPRIMARYKEYAUTOINCREMENT,LastNamevarchar(255)NOTNULL,FirstNamevarchar(255),Addressvarchar(255),Cityvarchar(255))MSAccess使用AUTOINCREMENT关键字来执行auto-increment任务。
默认地,AUTOINCREMENT的开始值是1,每条新纪录递增1。
要规定\"P_Id\"列以20起始且递增10,请把autoincrement改为AUTOINCREMENT(20,10)
要在\"Persons\"表中插入新纪录,我们不必为\"P_Id\"列规定值(会自动添加一个唯一的值):
INSERTINTOPersons(FirstName,LastName)VALUES('Bill','Gates')上面的SQL语句会在\"Persons\"表中插入一条新纪录。\"P_Id\"会被赋予一个唯一的值。\"FirstName\"会被设置为\"Bill\",\"LastName\"列会被设置为\"Gates\"。
用于Oracle的语法在Oracle中,代码稍微复杂一点。
您必须通过sequence对创建auto-increment字段(该对象生成数字序列)。
请使用下面的CREATESEQUENCE语法:
CREATESEQUENCEseq_personMINVALUE1STARTWITH1INCREMENTBY1CACHE10上面的代码创建名为seq_person的序列对象,它以1起始且以1递增。该对象缓存10个值以提高性能。CACHE选项规定了为了提高访问速度要存储多少个序列值。
要在\"Persons\"表中插入新纪录,我们必须使用nextval函数(该函数从seq_person序列中取回下一个值):
INSERTINTOPersons(P_Id,FirstName,LastName)VALUES(seq_person.nextval,'Lars','Monsen')上面的SQL语句会在\"Persons\"表中插入一条新纪录。\"P_Id\"的赋值是来自seq_person序列的下一个数字。\"FirstName\"会被设置为\"Bill\",\"LastName\"列会被设置为\"Gates\"。
SQLVIEW(视图)
视图是可视化的表。
本章讲解如何创建、更新和删除视图。
SQLCREATEVIEW语句什么是视图?
在SQL中,视图是基于SQL语句的结果集的可视化的表。
视图包含行和列,就像一个真实的表。视图中的字段就是来自一个或多个数据库中的真实的表中的字段。我们可以向视图添加SQL函数、WHERE以及JOIN语句,我们也可以提交数据,就像这些来自于某个单一的表。
注释:数据库的设计和结构不会受到视图中的函数、where或join语句的影响。
SQLCREATEVIEW语法CREATEVIEWview_nameASSELECTcolumn_name(s)FROMtable_nameWHEREcondition注释:视图总是显示最近的数据。每当用户查询视图时,数据库引擎通过使用SQL语句来重建数据。
SQLCREATEVIEW实例可以从某个查询内部、某个存储过程内部,或者从另一个视图内部来使用视图。通过向视图添加函数、join等等,我们可以向用户精确地提交我们希望提交的数据。
样本数据库Northwind拥有一些被默认安装的视图。视图\"CurrentProductList\"会从Products表列出所有正在使用的产品。这个视图使用下列SQL创建:
CREATEVIEWSELECTFROMProducts[CurrentProductList]ASProductID,ProductNameWHEREDiscontinued=No我们可以查询上面这个视图:
SELECT*FROM[CurrentProductList]Northwind样本数据库的另一个视图会选取Products表中所有单位价格高于平均单位价格的产品:
CREATEVIEWSELECTFROMWHEREProducts[ProductsAboveAveragePrice]ASProductName,UnitPriceUnitPrice>(SELECTAVG(UnitPrice)FROMProducts)我们可以像这样查询上面这个视图:
SELECT*FROM[ProductsAboveAveragePrice]另一个来自Northwind数据库的视图实例会计算在1997年每个种类的销售总数。请注意,这个视图会从另一个名为\"ProductSalesfor1997\"的视图那里选取数据:
CREATEVIEWFROM[CategorySalesFor1997]ASASCategorySalesSELECTDISTINCTGROUPBYCategoryName,Sum(ProductSales)[ProductSalesfor1997]CategoryName我们可以像这样查询上面这个视图:
SELECT*FROM[CategorySalesFor1997]我们也可以向查询添加条件。现在,我们仅仅需要查看\"Beverages\"类的全部销量:
SELECTWHERE*FROM[CategorySalesFor1997]CategoryName='Beverages'SQL更新视图您可以使用下面的语法来更新视图:
SQLCREATEORREPLACEVIEWSyntaxCREATEORREPLACEVIEWview_nameASSELECTcolumn_name(s)FROMtable_nameWHEREcondition现在,我们希望向\"CurrentProductList\"视图添加\"Category\"列。我们将通过下列SQL更新视图:
CREATEVIEW[CurrentProductList]ASSELECTProductID,ProductName,CategoryFROMProductsWHEREDiscontinued=NoSQL撤销视图您可以通过DROPVIEW命令来删除视图。
SQLDROPVIEWSyntaxDROPVIEWview_name函数篇
SQLDate函数
SQL日期当我们处理日期时,最难的任务恐怕是确保所插入的日期的格式,与数据库中日期列的格式相匹配。
只要数据包含的只是日期部分,运行查询就不会出问题。但是,如果涉及时间,情况就有点复杂了。
在讨论日期查询的复杂性之前,我们先来看看最重要的内建日期处理函数。
MySQLDate函数下面的表格列出了MySQL中最重要的内建日期函数:
函数描述NOW()返回当前的日期和时间CURDATE()返回当前的日期CURTIME()返回当前的时间DATE()提取日期或日期/时间表达式的日期部分EXTRACT()返回日期/时间按的单独部分DATE_ADD()给日期添加指定的时间间隔DATE_SUB()从日期减去指定的时间间隔DATEDIFF()返回两个日期之间的天数DATE_FORMAT()用不同的格式显示日期/时间SQLServerDate函数下面的表格列出了SQLServer中最重要的内建日期函数:
函数描述GETDATE()返回当前日期和时间DATEPART()返回日期/时间的单独部分DATEADD()在日期中添加或减去指定的时间间隔DATEDIFF()返回两个日期之间的时间CONVERT()用不同的格式显示日期/时间SQLDate数据类型MySQL使用下列数据类型在数据库中存储日期或日期/时间值:
DATE-格式YYYY-MM-DD
DATETIME-格式:YYYY-MM-DDHH:MM:SSTIMESTAMP-格式:YYYY-MM-DDHH:MM:SSYEAR-格式YYYY或YY
SQLServer使用下列数据类型在数据库中存储日期或日期/时间值:
DATE-格式YYYY-MM-DD
DATETIME-格式:YYYY-MM-DDHH:MM:SS
SMALLDATETIME-格式:YYYY-MM-DDHH:MM:SSTIMESTAMP-格式:唯一的数字
SQL日期处理如果不涉及时间部分,那么我们可以轻松地比较两个日期!
假设我们有下面这个\"Orders\"表:
OrderId1ProductNamecomputerOrderDate2008-12-262printer2008-12-263electrograph2008-11-124telephone2008-10-19现在,我们希望从上表中选取OrderDate为\"2008-12-26\"的记录。
我们使用如下SELECT语句:
SELECT*FROMOrdersWHEREOrderDate='2008-12-26'结果集:
OrderId1ProductNamecomputerOrderDate2008-12-263electrograph2008-12-26现在假设\"Orders\"类似这样(请注意\"OrderDate\"列中的时间部分):
OrderId1ProductNamecomputerOrderDate2008-12-2616:23:552printer2008-12-2610:45:263electrograph2008-11-1214:12:084telephone2008-10-1912:56:10如果我们使用上面的SELECT语句:
SELECT*FROMOrdersWHEREOrderDate='2008-12-26'那么我们得不到结果。这是由于该查询不含有时间部分的日期。
提示:如果您希望使查询简单且更易维护,那么请不要在日期中使用时间部分!
SQLNULL值
NULL值是遗漏的未知数据。
默认地,表的列可以存放NULL值。
本章讲解ISNULL和ISNOTNULL操作符。
SQLNULL值如果表中的某个列是可选的,那么我们可以在不向该列添加值的情况下插入新纪录或更新已有的记录。这意味着该字段将以NULL值保存。
NULL值的处理方式与其他值不同。
NULL用作未知的或不适用的值的占位符。
注释:无法比较NULL和0;它们是不等价的。
SQL的NULL值处理请看下面的\"Persons\"表:
Id1LastNameAdamsFirstNameJohnAddressCityLondon2BushGeorgeFifthAvenueNewYork3CarterThomasBeijing假如\"Persons\"表中的\"Address\"列是可选的。这意味着如果在\"Address\"列插入一条不带值的记录,\"Address\"列会使用NULL值保存。
那么我们如何测试NULL值呢?
无法使用比较运算符来测试NULL值,比如=,<,或者<>。
我们必须使用ISNULL和ISNOTNULL操作符。
SQLISNULL我们如何仅仅选取在\"Address\"列中带有NULL值的记录呢?
我们必须使用ISNULL操作符:
SELECTLastName,FirstName,AddressFROMPersonsWHEREAddressISNULL结果集:
LastNameAdamsFirstNameJohnAddressCarterThomas提示:请始终使用ISNULL来查找NULL值。
SQLISNOTNULL我们如何选取在\"Address\"列中不带有NULL值的记录呢?
我们必须使用ISNOTNULL操作符:
SELECTLastName,FirstName,AddressFROMPersonsWHEREAddressISNOTNULL结果集:
LastNameBushFirstNameGeorgeAddressFifthAvenue在下一节中,我们了解ISNULL()、NVL()、IFNULL()和COALESCE()函数。
SQLNULL函数
SQLISNULL()、NVL()、IFNULL()和COALESCE()函数请看下面的\"Products\"表:
P_Id1ProductNamecomputerUnitPrice699UnitsInStock25UnitsOnOrder152printer365363telephone28015957假如\"UnitsOnOrder\"是可选的,而且可以包含NULL值。
我们使用如下SELECT语句:
SELECTProductName,UnitPrice*(UnitsInStock+UnitsOnOrder)FROMProducts在上面的例子中,如果有\"UnitsOnOrder\"值是NULL,那么结果是NULL。
微软的ISNULL()函数用于规定如何处理NULL值。
NVL(),IFNULL()和COALESCE()函数也可以达到相同的结果。
在这里,我们希望NULL值为0。
下面,如果\"UnitsOnOrder\"是NULL,则不利于计算,因此如果值是NULL则ISNULL()返回0。
SQLServer/MSAccess
SELECTProductName,UnitPrice*(UnitsInStock+ISNULL(UnitsOnOrder,0))FROMProductsOracle
Oracle没有ISNULL()函数。不过,我们可以使用NVL()函数达到相同的结果:
SELECTProductName,UnitPrice*(UnitsInStock+NVL(UnitsOnOrder,0))FROMProductsMySQL
MySQL也拥有类似ISNULL()的函数。不过它的工作方式与微软的ISNULL()函数有点不同。
在MySQL中,我们可以使用IFNULL()函数,就像这样:
SELECTProductName,UnitPrice*(UnitsInStock+IFNULL(UnitsOnOrder,0))FROMProducts或者我们可以使用COALESCE()函数,就像这样:
SELECTProductName,UnitPrice*(UnitsInStock+COALESCE(UnitsOnOrder,0))FROMProductsSQL数据类型
MicrosoftAccess、MySQL以及SQLServer所使用的数据类型和范围。
MicrosoftAccess数据类型数据类型描述存储Text用于文本或文本与数字的组合。最多255个字符。Memo用于更大数量的文本。最多存储65,536个字符。注释:无法对memo字段进行排序。不过它们是可搜索的。MemoByteIntegerLongSingleDoubleCurrency允许0到255的数字。允许介于-32,768到32,767之间的数字。允许介于-2,147,483,8与2,147,483,7之间的全部数字单精度浮点。处理大多数小数。双精度浮点。处理大多数小数。用于货币。支持15位的元,外加4位小数。提示:您可以选择使用哪个国家的货币。1字节2字节4字节4字节8字节8字节AutoNumberDate/TimeYes/NoAutoNumber字段自动为每条记录分配数字,通常从1开始。用于日期和时间逻辑字段,可以显示为Yes/No、True/False或On/Off。在代码中,使用常量True和False(等价于1和0)注释:Yes/No字段中不允许Null值4字节8字节1比特OleObjectHyperlinkLookupWizard可以存储图片、音频、视频或其他BLOBs(BinaryLargeOBjects)包含指向其他文件的链接,包括网页。允许你创建一个可从下列列表中进行选择的选项列表。最多1GB4字节MySQL数据类型在MySQL中,有三种主要的类型:文本、数字和日期/时间类型。
Text类型:数据类型描述CHAR(size)保存固定长度的字符串(可包含字母、数字以及特殊字符)。在括号中指定字符串的长度。最多255个字符。保存可变长度的字符串(可包含字母、数字以及特殊字符)。在括号中指定字符串的最大长度。最多255个字符。注释:如果值的长度大于255,则被转换为TEXT类型。VARCHAR(size)TINYTEXTTEXTBLOBMEDIUMTEXTMEDIUMBLOBLONGTEXTLONGBLOBENUM(x,y,z,etc.)存放最大长度为255个字符的字符串。存放最大长度为65,535个字符的字符串。用于BLOBs(BinaryLargeOBjects)。存放最多65,535字节的数据。存放最大长度为16,777,215个字符的字符串。用于BLOBs(BinaryLargeOBjects)。存放最多16,777,215字节的数据。存放最大长度为4,294,967,295个字符的字符串。用于BLOBs(BinaryLargeOBjects)。存放最多4,294,967,295字节的数据。允许你输入可能值的列表。可以在ENUM列表中列出最大65535个值。如果列表中不存在插入的值,则插入空值。注释:这些值是按照你输入的顺序存储的。可以按照此格式输入可能的值:ENUM('X','Y','Z')SET与ENUM类似,SET最多只能包含个列表项,不过SET可存储一个以上的值。Number类型:数据类型描述TINYINT(size)-128到127常规。0到255无符号*。在括号中规定最大位数。SMALLINT(size)-32768到32767常规。0到65535无符号*。在括号中规定最大位数。MEDIUMINT(size)-8388608到8388607普通。0to16777215无符号*。在括号中规定最大位数。INT(size)-21474838到21474837常规。0到4294967295无符号*。在括号中规定最大位数。BIGINT(size)-9223372036854775808到9223372036854775807常规。0到18446744073709551615无符号*。在括号中规定最大位数。FLOAT(size,d)带有浮动小数点的小数字。在括号中规定最大位数。在d参数中规定小数点右侧的最大位数。DOUBLE(size,d)带有浮动小数点的大数字。在括号中规定最大位数。在d参数中规定小数点右侧的最大位数。DECIMAL(size,d)作为字符串存储的DOUBLE类型,允许固定的小数点。*这些整数类型拥有额外的选项UNSIGNED。通常,整数可以是负数或正数。如果添加UNSIGNED属性,那么范围将从0开始,而不是某个负数。
Date类型:数据类型描述日期。格式:YYYY-MM-DD注释:支持的范围是从'1000-01-01'到'9999-12-31'DATE()DATETIME()*日期和时间的组合。格式:YYYY-MM-DDHH:MM:SS注释:支持的范围是从'1000-01-0100:00:00'到'9999-12-3123:59:59'TIMESTAMP()*时间戳。TIMESTAMP值使用Unix纪元('1970-01-0100:00:00'UTC)至今的描述来存储。格式:YYYY-MM-DDHH:MM:SS注释:支持的范围是从'1970-01-0100:00:01'UTC到'2038-01-0903:14:07'UTCTIME()YEAR()时间。格式:HH:MM:SS注释:支持的范围是从'-838:59:59'到'838:59:59'2位或4位格式的年。注释:4位格式所允许的值:1901到2155。2位格式所允许的值:70到69,表示从1970到2069。*即便DATETIME和TIMESTAMP返回相同的格式,它们的工作方式很不同。在INSERT或UPDATE查询中,TIMESTAMP自动把自身设置为当前的日期和时间。TIMESTAMP也接受不同的格式,比如YYYYMMDDHHMMSS、YYMMDDHHMMSS、YYYYMMDD或YYMMDD。
SQLServer数据类型Character字符串:数据类型描述存储char(n)固定长度的字符串。最多8,000个字符。nvarchar(n)可变长度的字符串。最多8,000个字符。varchar(max)可变长度的字符串。最多1,073,741,824个字符。text可变长度的字符串。最多2GB字符数据。Unicode字符串:数据类型描述存储nchar(n)固定长度的Unicode数据。最多4,000个字符。nvarchar(n)可变长度的Unicode数据。最多4,000个字符。nvarchar(max)可变长度的Unicode数据。最多536,870,912个字符。ntext可变长度的Unicode数据。最多2GB字符数据。Binary类型:数据类型描述存储bit允许0、1或NULLbinary(n)固定长度的二进制数据。最多8,000字节。varbinary(n)可变长度的二进制数据。最多8,000字节。varbinary(max)可变长度的二进制数据。最多2GB字节。image可变长度的二进制数据。最多2GB。Number类型:
数据类型描述存储tinyint允许从0到255的所有数字。1字节smallint允许从-32,768到32,767的所有数字。2字节int允许从-2,147,483,8到2,147,483,7的所有数字。4字节bigint允许介于-9,223,372,036,854,775,808和9,223,372,036,854,775,807之间的所有数字。固定精度和比例的数字。允许从-10^38+1到10^38-1之间的数字。p参数指示可以存储的最大位数(小数点左侧和右侧)。p必须是1到38之间的值。默认是18。s参数指示小数点右侧存储的最大位数。s必须是0到p之间的值。默认是0。8字节decimal(p,s)5-17字节numeric(p,s)固定精度和比例的数字。允许从-10^38+1到10^38-1之间的数字。p参数指示可以存储的最大位数(小数点左侧和右侧)。p必须是1到38之间的值。默认是18。s参数指示小数点右侧存储的最大位数。s必须是0到p之间的值。默认是0。5-17字节smallmoneymoney介于-214,748.38和214,748.37之间的货币数据。介于-922,337,203,685,477.5808和922,337,203,685,477.5807之间的货币数据。4字节8字节float(n)从-1.79E+308到1.79E+308的浮动精度数字数据。参数n指示该字段保存4字节还是8字节。float(24)保存4字节,而float(53)保存8字节。n的默认值是53。4或8字节real从-3.40E+38到3.40E+38的浮动精度数字数据。4字节Date类型:数据类型描述存储datetime从1753年1月1日到9999年12月31日,精度为3.33毫秒。8bytesdatetime2从1753年1月1日到9999年12月31日,精度为100纳秒。6-8bytessmalldatetime从1900年1月1日到2079年6月6日,精度为1分钟。4bytesdate仅存储日期。从0001年1月1日到9999年12月31日。3bytestime仅存储时间。精度为100纳秒。3-5bytesdatetimeoffset与datetime2相同,外加时区偏移。8-10bytestimestamp存储唯一的数字,每当创建或修改某行时,该数字会更新。timestamp基于内部时钟,不对应真实时间。每个表只能有一个timestamp变量。其他数据类型:数据类型描述sql_variant存储最多8,000字节不同数据类型的数据,除了text、ntext以及timestamp。uniqueidentifier存储全局标识符(GUID)。xml存储XML格式化数据。最多2GB。cursor存储对用于数据库操作的指针的引用。table存储结果集,供稍后处理。SQL服务器–RDBMS
现代的SQL服务器构建在RDBMS之上。
DBMS-数据库管理系统(DatabaseManagementSystem)数据库管理系统是一种可以访问数据库中数据的计算机程序。
DBMS使我们有能力在数据库中提取、修改或者存贮信息。
不同的DBMS提供不同的函数供查询、提交以及修改数据。
RDBMS-关系数据库管理系统(RelationalDatabaseManagementSystem)关系数据库管理系统(RDBMS)也是一种数据库管理系统,其数据库是根据数据间的关系来组织和访问数据的。
20世纪70年代初,IBM公司发明了RDBMS。
RDBMS是SQL的基础,也是所有现代数据库系统诸如Oracle、SQLServer、IBMDB2、Sybase、MySQL以及MicrosoftAccess的基础。
SQL函数
SQL拥有很多可用于计数和计算的内建函数。
函数的语法内建SQL函数的语法是:
SELECTfunction(列)FROM表函数的类型在SQL中,基本的函数类型和种类有若干种。函数的基本类型是:
Aggregate函数Scalar函数
合计函数(Aggregatefunctions)Aggregate函数的操作面向一系列的值,并返回一个单一的值。
注释:如果在SELECT语句的项目列表中的众多其它表达式中使用SELECT语句,则这个SELECT必须使用GROUPBY语句!
\"Persons\"table(在大部分的例子中使用过)NameAdams,JohnAge38Bush,George33Carter,Thomas28MSAccess中的合计函数函数描述AVG(column)返回某列的平均值COUNT(column)返回某列的行数(不包括NULL值)COUNT(*)返回被选行数FIRST(column)返回在指定的域中第一个记录的值LAST(column)返回在指定的域中最后一个记录的值MAX(column)返回某列的最高值MIN(column)返回某列的最低值STDEV(column)STDEVP(column)SUM(column)返回某列的总和VAR(column)VARP(column)在SQLServer中的合计函数函数描述AVG(column)返回某列的行数BINARY_CHECKSUMCHECKSUMCHECKSUM_AGGCOUNT(column)返回某列的行数(不包括NULL值)COUNT(*)返回被选行数COUNT(DISTINCTcolumn)返回相异结果的数目FIRST(column)返回在指定的域中第一个记录的值(SQLServer2000不支持)LAST(column)返回在指定的域中最后一个记录的值(SQLServer2000不支持)MAX(column)返回某列的最高值MIN(column)返回某列的最低值STDEV(column)STDEVP(column)SUM(column)返回某列的总和VAR(column)VARP(column)Scalar函数Scalar函数的操作面向某个单一的值,并返回基于输入值的一个单一的值。
MSAccess中的Scalar函数函数描述UCASE(c)将某个域转换为大写LCASE(c)将某个域转换为小写MID(c,start[,end])从某个文本域提取字符LEN(c)返回某个文本域的长度INSTR(c,char)返回在某个文本域中指定字符的数值位置LEFT(c,number_of_char)返回某个被请求的文本域的左侧部分RIGHT(c,number_of_char)返回某个被请求的文本域的右侧部分ROUND(c,decimals)对某个数值域进行指定小数位数的四舍五入MOD(x,y)返回除法操作的余数NOW()返回当前的系统日期FORMAT(c,format)改变某个域的显示方式DATEDIFF(d,date1,date2)用于执行日期计算SQLAVG函数
定义和用法AVG函数返回数值列的平均值。NULL值不包括在计算中。
SQLAVG()语法
SELECTAVG(column_name)FROMtable_nameSQLAVG()实例我们拥有下面这个\"Orders\"表:
O_Id1OrderDate2008/12/29OrderPrice1000CustomerBush22008/11/231600Carter32008/10/05700Bush42008/09/28300Bush52008/08/062000Adams62008/07/21100Carter例子1
现在,我们希望计算\"OrderPrice\"字段的平均值。
我们使用如下SQL语句:
SELECTAVG(OrderPrice)ASOrderAverageFROMOrders结果集类似这样:
OrderAverage950例子2
现在,我们希望找到OrderPrice值高于OrderPrice平均值的客户。
我们使用如下SQL语句:
SELECTCustomerFROMOrdersWHEREOrderPrice>(SELECTAVG(OrderPrice)FROMOrders)结果集类似这样:
CustomerBushCarterAdamsSQLCOUNT()函数
COUNT()函数返回匹配指定条件的行数。
SQLCOUNT()语法SQLCOUNT(column_name)语法
COUNT(column_name)函数返回指定列的值的数目(NULL不计入):
SELECTCOUNT(column_name)FROMtable_nameSQLCOUNT(*)语法
COUNT(*)函数返回表中的记录数:
SELECTCOUNT(*)FROMtable_nameSQLCOUNT(DISTINCTcolumn_name)语法
COUNT(DISTINCTcolumn_name)函数返回指定列的不同值的数目:
SELECTCOUNT(DISTINCTcolumn_name)FROMtable_name注释:COUNT(DISTINCT)适用于ORACLE和MicrosoftSQLServer,但是无法用于MicrosoftAccess。
SQLCOUNT(column_name)实例我们拥有下列\"Orders\"表:
O_Id1OrderDate2008/12/29OrderPrice1000CustomerBush22008/11/231600Carter32008/10/05700Bush42008/09/28300Bush52008/08/062000Adams62008/07/21100Carter现在,我们希望计算客户\"Carter\"的订单数。
我们使用如下SQL语句:
SELECTCOUNT(Customer)ASCustomerNilsenFROMOrdersWHERECustomer='Carter'以上SQL语句的结果是2,因为客户Carter共有2个订单:
CustomerNilsen2SQLCOUNT(*)实例
如果我们省略WHERE子句,比如这样:
SELECTCOUNT(*)ASNumberOfOrdersFROMOrders结果集类似这样:
NumberOfOrders6这是表中的总行数。
SQLCOUNT(DISTINCTcolumn_name)实例现在,我们希望计算\"Orders\"表中不同客户的数目。
我们使用如下SQL语句:
SELECTCOUNT(DISTINCTCustomer)ASNumberOfCustomersFROMOrders结果集类似这样:
NumberOfCustomers3这是\"Orders\"表中不同客户(Bush,Carter和Adams)的数目。
SQLFIRST()函数
FIRST()函数FIRST()函数返回指定的字段中第一个记录的值。
提示:可使用ORDERBY语句对记录进行排序。
SQLFIRST()语法
SELECTFIRST(column_name)FROMtable_nameSQLFIRST()实例我们拥有下面这个\"Orders\"表:
O_Id1OrderDate2008/12/29OrderPrice1000CustomerBush22008/11/231600Carter32008/10/05700Bush42008/09/28300Bush52008/08/062000Adams62008/07/21100Carter现在,我们希望查找\"OrderPrice\"列的第一个值。
我们使用如下SQL语句:
SELECTFIRST(OrderPrice)ASFirstOrderPriceFROMOrders结果集类似这样:
FirstOrderPrice1000SQLLAST()函数
LAST()函数LAST()函数返回指定的字段中最后一个记录的值。
提示:可使用ORDERBY语句对记录进行排序。
SQLLAST()语法
SELECTLAST(column_name)FROMtable_nameSQLLAST()实例我们拥有下面这个\"Orders\"表:
O_Id1OrderDate2008/12/29OrderPrice1000CustomerBush22008/11/231600Carter32008/10/05700Bush42008/09/28300Bush52008/08/062000Adams62008/07/21100Carter现在,我们希望查找\"OrderPrice\"列的最后一个值。
我们使用如下SQL语句:
SELECTLAST(OrderPrice)ASLastOrderPriceFROMOrders结果集类似这样:
LastOrderPrice100SQLMAX()函数
MAX()函数MAX函数返回一列中的最大值。NULL值不包括在计算中。
SQLMAX()语法
SELECTMAX(column_name)FROMtable_name注释:MIN和MAX也可用于文本列,以获得按字母顺序排列的最高或最低值。
SQLMAX()实例我们拥有下面这个\"Orders\"表:
O_Id1OrderDate2008/12/29OrderPrice1000CustomerBush22008/11/231600Carter32008/10/05700Bush42008/09/28300Bush52008/08/062000Adams62008/07/21100Carter现在,我们希望查找\"OrderPrice\"列的最大值。
我们使用如下SQL语句:
SELECTMAX(OrderPrice)ASLargestOrderPriceFROMOrders结果集类似这样:
LargestOrderPrice2000SQLMIN()函数
MIN()函数MIN函数返回一列中的最小值。NULL值不包括在计算中。
SQLMIN()语法
SELECTMIN(column_name)FROMtable_name注释:MIN和MAX也可用于文本列,以获得按字母顺序排列的最高或最低值。
SQLMIN()实例我们拥有下面这个\"Orders\"表:
O_Id1OrderDate2008/12/29OrderPrice1000CustomerBush22008/11/231600Carter32008/10/05700Bush42008/09/28300Bush52008/08/062000Adams62008/07/21100Carter现在,我们希望查找\"OrderPrice\"列的最小值。
我们使用如下SQL语句:
SELECTMIN(OrderPrice)ASSmallestOrderPriceFROMOrders结果集类似这样:
SmallestOrderPrice100SQLSUM()函数
SUM函数返回数值列的总数(总额)。
SQLSUM()语法
SELECTSUM(column_name)FROMtable_nameSQLSUM()实例我们拥有下面这个\"Orders\"表:
O_Id1OrderDate2008/12/29OrderPrice1000CustomerBush22008/11/231600Carter32008/10/05700Bush42008/09/28300Bush52008/08/062000Adams62008/07/21100Carter现在,我们希望查找\"OrderPrice\"字段的总数。
我们使用如下SQL语句:
SELECTSUM(OrderPrice)ASOrderTotalFROMOrders结果集类似这样:
OrderTotal5700SQLGROUPBY语句
合计函数(比如SUM)常常需要添加GROUPBY语句。
GROUPBY语句GROUPBY语句用于结合合计函数,根据一个或多个列对结果集进行分组。
SQLGROUPBY语法
SELECTcolumn_name,aggregate_function(column_name)FROMtable_nameWHEREcolumn_nameoperatorvalueGROUPBYcolumn_nameSQLGROUPBY实例我们拥有下面这个\"Orders\"表:
O_Id1OrderDate2008/12/29OrderPrice1000CustomerBush22008/11/231600Carter32008/10/05700Bush42008/09/28300Bush52008/08/062000Adams62008/07/21100Carter现在,我们希望查找每个客户的总金额(总订单)。
我们想要使用GROUPBY语句对客户进行组合。
我们使用下列SQL语句:
SELECTCustomer,SUM(OrderPrice)FROMOrdersGROUPBYCustomer结果集类似这样:
CustomerBushSUM(OrderPrice)2000Carter1700Adams2000很棒吧,对不对?
让我们看一下如果省略GROUPBY会出现什么情况:
SELECTCustomer,SUM(OrderPrice)FROMOrders结果集类似这样:
CustomerBushSUM(OrderPrice)5700Carter5700Bush5700Bush5700Adams5700Carter5700上面的结果集不是我们需要的。
那么为什么不能使用上面这条SELECT语句呢?解释如下:上面的SELECT语句指定了两列(Customer和SUM(OrderPrice))。\"SUM(OrderPrice)\"返回一个单独的值(\"OrderPrice\"列的总计),而\"Customer\"返回6个值(每个值对应\"Orders\"表中的每一行)。因此,我们得不到正确的结果。不过,您已经看到了,GROUPBY语句解决了这个问题。
GROUPBY一个以上的列我们也可以对一个以上的列应用GROUPBY语句,就像这样:
SELECTCustomer,OrderDate,SUM(OrderPrice)FROMOrdersGROUPBYCustomer,OrderDateSQLHAVING子句
HAVING子句在SQL中增加HAVING子句原因是,WHERE关键字无法与合计函数一起使用。
SQLHAVING语法
SELECTcolumn_name,aggregate_function(column_name)FROMtable_nameWHEREcolumn_nameoperatorvalueGROUPBYcolumn_nameHAVINGaggregate_function(column_name)operatorvalueSQLHAVING实例我们拥有下面这个\"Orders\"表:
O_Id1OrderDate2008/12/29OrderPrice1000CustomerBush22008/11/231600Carter32008/10/05700Bush42008/09/28300Bush52008/08/062000Adams62008/07/21100Carter现在,我们希望查找订单总金额少于2000的客户。
我们使用如下SQL语句:
SELECTCustomer,SUM(OrderPrice)FROMOrdersGROUPBYCustomerHAVINGSUM(OrderPrice)<2000结果集类似:
CustomerCarterSUM(OrderPrice)1700现在我们希望查找客户\"Bush\"或\"Adams\"拥有超过1500的订单总金额。
我们在SQL语句中增加了一个普通的WHERE子句:
SELECTCustomer,SUM(OrderPrice)FROMOrdersWHERECustomer='Bush'ORCustomer='Adams'GROUPBYCustomerHAVINGSUM(OrderPrice)>1500结果集:
CustomerBushSUM(OrderPrice)2000Adams2000SQLUCASE()函数
UCASE()函数UCASE函数把字段的值转换为大写。
SQLUCASE()语法
SELECTUCASE(column_name)FROMtable_nameSQLUCASE()实例我们拥有下面这个\"Persons\"表:
Id1LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondon2BushGeorgeFifthAvenueNewYork3CarterThomasChanganStreetBeijing现在,我们希望选取\"LastName\"和\"FirstName\"列的内容,然后把\"LastName\"列转换为大写。
我们使用如下SQL语句:
SELECTUCASE(LastName)asLastName,FirstNameFROMPersons结果集类似这样:
LastNameADAMSFirstNameJohnBUSHGeorgeCARTERThomasSQLLCASE()函数
LCASE()函数LCASE函数把字段的值转换为小写。
SQLLCASE()语法
SELECTLCASE(column_name)FROMtable_nameSQLLCASE()实例我们拥有下面这个\"Persons\"表:
Id1LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondon2BushGeorgeFifthAvenueNewYork3CarterThomasChanganStreetBeijing现在,我们希望选取\"LastName\"和\"FirstName\"列的内容,然后把\"LastName\"列转换为小写。
我们使用如下SQL语句:
SELECTLCASE(LastName)asLastName,FirstNameFROMPersons结果集类似这样:
LastNameadamsFirstNameJohnbushGeorgecarterThomasSQLMID()函数
MID()函数MID函数用于从文本字段中提取字符。
SQLMID()语法
SELECTMID(column_name,start[,length])FROMtable_name参数描述column_name必需。要提取字符的字段。start必需。规定开始位置(起始值是1)。length可选。要返回的字符数。如果省略,则MID()函数返回剩余文本。SQLMID()实例我们拥有下面这个\"Persons\"表:
Id1LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondon2BushGeorgeFifthAvenueNewYork3CarterThomasChanganStreetBeijing现在,我们希望从\"City\"列中提取前3个字符。
我们使用如下SQL语句:
SELECTMID(City,1,3)asSmallCityFROMPersons结果集类似这样:
SmallCityLonNewBeiSQLLEN()函数
LEN()函数LEN函数返回文本字段中值的长度。
SQLLEN()语法
SELECTLEN(column_name)FROMtable_nameSQLLEN()实例我们拥有下面这个\"Persons\"表:
Id1LastNameAdamsFirstNameJohnAddressOxfordStreetCityLondon2BushGeorgeFifthAvenueNewYork3CarterThomasChanganStreetBeijing现在,我们希望取得\"City\"列中值的长度。
我们使用如下SQL语句:
SELECTLEN(City)asLengthOfCityFROMPersons结果集类似这样:
LengthOfCity687SQLROUND()函数
ROUND()函数ROUND函数用于把数值字段舍入为指定的小数位数。
SQLROUND()语法
SELECTROUND(column_name,decimals)FROMtable_name参数描述column_name必需。要舍入的字段。decimals必需。规定要返回的小数位数。SQLROUND()实例我们拥有下面这个\"Products\"表:
Prod_Id1ProductNamegoldUnit1000gUnitPrice32.352silver1000g11.563copper1000g6.85现在,我们希望把名称和价格舍入为最接近的整数。
我们使用如下SQL语句:
SELECTProductName,ROUND(UnitPrice,0)asUnitPriceFROMProducts结果集类似这样:
ProductNamegoldUnitPrice32silver12copper7SQLNOW()函数
NOW()函数NOW函数返回当前的日期和时间。
提示:如果您在使用SqlServer数据库,请使用getdate()函数来获得当前的日期时间。
SQLNOW()语法
SELECTNOW()FROMtable_nameSQLNOW()实例我们拥有下面这个\"Products\"表:
Prod_Id1ProductNamegoldUnit1000gUnitPrice32.352silver1000g11.563copper1000g6.85现在,我们希望显示当天的日期所对应的名称和价格。
我们使用如下SQL语句:
SELECTProductName,UnitPrice,Now()asPerDateFROMProducts结果集类似这样:
ProductNamegoldUnitPrice32.35PerDate12/29/200811:36:05AMsilver11.5612/29/200811:36:05AMcopper6.8512/29/200811:36:05AMSQLFORMAT()函数
FORMAT()函数FORMAT函数用于对字段的显示进行格式化。
SQLFORMAT()语法
SELECTFORMAT(column_name,format)FROMtable_name参数描述column_name必需。要格式化的字段。format必需。规定格式。SQLFORMAT()实例我们拥有下面这个\"Products\"表:
Prod_Id1ProductNamegoldUnit1000gUnitPrice32.352silver1000g11.563copper1000g6.85现在,我们希望显示每天日期所对应的名称和价格(日期的显示格式是\"YYYY-MM-DD\")。
我们使用如下SQL语句:
SELECTProductName,UnitPrice,FORMAT(Now(),'YYYY-MM-DD')asPerDateFROMProducts结果集类似这样:
ProductNamegoldUnitPrice32.35PerDate12/29/2008silver11.5612/29/2008copper6.8512/29/2008SQL快速参考
来自W3School的SQL快速参考。可以打印它,以备日常使用。
SQL语句语句语法AND/ORSELECTcolumn_name(s)FROMtable_nameWHEREconditionAND|ORconditionALTERTABLE(addcolumn)ALTERTABLEtable_nameADDcolumn_namedatatypeALTERTABLE(dropcolumn)ALTERTABLEtable_nameDROPCOLUMNcolumn_nameAS(aliasforcolumn)SELECTcolumn_nameAScolumn_aliasFROMtable_nameAS(aliasfortable)SELECTcolumn_nameFROMtable_nameAStable_aliasBETWEENSELECTcolumn_name(s)FROMtable_nameWHEREcolumn_nameBETWEENvalue1ANDvalue2CREATEDATABASECREATEDATABASEdatabase_nameCREATEINDEXCREATEINDEXindex_nameONtable_name(column_name)CREATETABLECREATETABLEtable_name(column_name1data_type,column_name2data_type,.......)CREATEUNIQUEINDEXCREATEUNIQUEINDEXindex_nameONtable_name(column_name)CREATEVIEWCREATEVIEWview_nameASSELECTcolumn_name(s)FROMtable_nameWHEREconditionDELETEFROMDELETEFROMtable_name(Note:Deletestheentiretable!!)orDELETEFROMtable_nameWHEREconditionDROPDATABASEDROPINDEXDROPTABLEGROUPBYDROPDATABASEdatabase_nameDROPINDEXtable_name.index_nameDROPTABLEtable_nameSELECTcolumn_name1,SUM(column_name2)FROMtable_nameGROUPBYcolumn_name1HAVINGSELECTcolumn_name1,SUM(column_name2)FROMtable_nameGROUPBYcolumn_name1HAVINGSUM(column_name2)conditionvalueINSELECTcolumn_name(s)FROMtable_nameWHEREcolumn_nameIN(value1,value2,..)INSERTINTOINSERTINTOtable_nameVALUES(value1,value2,....)orINSERTINTOtable_name(column_name1,column_name2,...)VALUES(value1,value2,....)LIKESELECTcolumn_name(s)FROMtable_nameWHEREcolumn_nameLIKEpatternORDERBYSELECTcolumn_name(s)FROMtable_nameORDERBYcolumn_name[ASC|DESC]SELECTSELECTcolumn_name(s)FROMtable_nameSELECT*SELECT*FROMtable_nameSELECTDISTINCTSELECTDISTINCTcolumn_name(s)FROMtable_nameSELECTINTOSELECT*(usedtocreatebackupcopiesoftables)INTOnew_table_nameFROMoriginal_table_nameorSELECTcolumn_name(s)INTOnew_table_nameFROMoriginal_table_nameTRUNCATETABLE(deletesonlythedatainsidethetable)UPDATETRUNCATETABLEtable_nameUPDATEtable_nameSETcolumn_name=new_value[,column_name=new_value]WHEREcolumn_name=some_valueWHERESELECTcolumn_name(s)FROMtable_nameWHEREcondition我们已经学习了SQL,下一步学习什么呢?
SQL概要本教程已经向您讲解了用来访问和处理数据库系统的标准计算机语言。
我们已经学习了如何使用SQL在数据库中执行查询、获取数据、插入新的纪录、删除记录以及更新记录。
SQL是一种与数据库程序协同工作的标准语言,这些数据库程序包括MSAccess、DB2、Informix、MSSQLServer、Oracle、MySQL、Sybase等等。
我们已经学习了SQL,下一步学习什么呢?下一步应该学习ADO。
ADO是一种从网站访问数据库中数据的编程接口。
ADO使用SQL来查询数据库中的数据。
如果您需要学习更多关于ADO的知识,请访问我们的《ADO教程》。
因篇幅问题不能全部显示,请点此查看更多更全内容