网站导航网学 原创论文 原创专题 网站设计 最新系统 原创论文 论文降重 发表论文 论文发表 UI设计定制 论文答辩PPT格式排版 期刊发表 论文专题
返回网学首页
网学原创论文
最新论文 推荐专题 热门论文 论文专题
当前位置: 网学 > 交易代码 > SQL语法 > 正文

SQL电子书(1)

论文降重修改服务、格式排版等 获取论文 论文降重及排版 论文发表 相关服务
SQL循序渐进
    (1)介绍SQL
    介绍SQL
    SQL(StructuredQueryLanguage,结构查询语言)是一个功能强大的数据库语言。SQL通常使用于数据库的通讯。ANSI(美国国家标准学会)声称,SQL是关系数据库管理系统的标准语言。SQL语句通常用于完成一些数据库的操作任务,比如在数据库中更新数据,或者从数据库中检索数据。使用SQL的常见关系数据库管理系统有:Oracle、Sybase、MicrosoftSQLServer、Access、Ingres等等。虽然绝大多数的数据库系统使用SQL,但是它们同样有它们自立另外的专有扩展功能用于它们的系统。但是,标准的SQL命令,比如"Select"、"Insert"、"Update"、"Delete"、"Create"和"Drop"常常被用于完成绝大多数数据库的操作。
    但是,不象其它的语言,如C、Pascal等,SQL没有循环结构(比如if-then-else、do-while)以及函数定义等等的功能。而且SQL只有一个数据类型的固定设置,换句话说,你不能在使用其它编程语言的时候创建你自己的数据类型。
    SQL功能强大,但是概括起来,它可以分成以下几组:
    DML(DataManipulationLanguage,数据操作语言):用于检索或者修改数据;
    DDL(DataDefinitionLanguage,数据定义语言):用于定义数据的结构,比如创建、修改或者删除数据库对象;
    DCL(DataControlLanguage,数据控制语言):用于定义数据库用户的权限。
    DML组可以细分为以下的几个语句:
    SELECT:用于检索数据;
    INSERT:用于增加数据到数据库;
    UPDATE:用于从数据库中修改现存的数据
    DELETE:用于从数据库中删除数据。
    DDL语句可以用于创建用户和重建数据库对象。下面是DDL命令:
    CREATETABLE
    ALTERTABLE
    DROPTABLE
    CREATEINDEX
    DROPINDEX
    DCL命令用于创建关系用户访问以及授权的对象。下面是几个DCL命令:
    ALTERPASSWORD
    GRANT
    REVOKE
    CREATESYNONYM
    为了让你对SQL有一个直观的认识,下面先给出一个简单SQL语句的例子:
    我们使用SQL语句来从Employees中检索DepartmentID为CS的:
    SELECTEmployees.Name
    FROMEmployees
    WHEREEmployees.DeptID="CS"
    可能你现在一开始不太理解这些语句,也许你会一头雾水,不要紧的,通过本教程的学习后,你会发现这段语句是多么的普通。为了不让你困惑,下面我也进行一番解释:
    先对FROM子句吧,语句中的FROMEmployees意思是从Employees表中检索数据。
    而语句WHEREEmployees.DeptID="CS"意思是检索Employees的DeptID列为”CS”的行,这样SQL语句检索的结果将是DeptID为CS的列的所有数据,比如:
    EmpID
    Name
    Dept
    123
    Purple
    CS
    124
    Zsc
    CS
    最后,我们来解释一个SELECT子句,它指定了从Name列检索来的所有数据,比如
    Name
    Purple
    Zsc
    好吧,开始我们下一节的教程-------表的基本知识。
    (2)表的基础知识
    表的基础知识
    关系数据库通常包含多个表。数据库实际上是表的集合,数据库的数据或者信息都是存储在表中的。表是对数据进行存储和操作的一种逻辑结构,每一个表都代表一个对用户意义的对象。例如,一个公司数据库中,会有雇员表、部门表、库存表、销售表、工资表等等。我们经常见到的成绩表就是一种表,它是有行和列组成的,我们并且可以通过名字来识别数据。列包含了列的名字、数据类型以及列的其它属性;行包含了列的记录或者数据。下面给出一个成绩单,其中、语文、数学、英语都是列,而行包含了这个表的数据,即每个人的各科成绩:
    语文数学英语
    王小童7810087
    张柳风859295
    紫云飞658986
    黄天龙986775
    (3)数据检索
    数据检索
    在SQL中SELECT语句通常用于检索数据库,或者检索满足你设定条件的数据,以下是简单的SELECT语句的格式:
    select"column1"[,"column2",etc]from"tablename"
    [where"condition"];
    []=optional
    其中列的名字跟着SELECT关键字,它决定了哪一列将被作为结果返回。你可以任意指定多个列,或者你可以使用"*"来选择所有的列。
    表的名字是紧跟着FROM关键字的,它指出了哪个表格将作为最后结果被查询。
    而WHERE子句(可选)指出哪个数据或者行将被返回或者显示,它是根据关键字WHERE后面描述的条件而来的。
    在WHERE子句中可以有以下的条件选择:
    =等于
    >大于
    <小于
    >=大于等于
    <=小于等于
    <>不等于
    LIKE参见以下注释
    注释:LIKE模式匹配操作符同样可以使用在WHERE子句的条件条件中。LIKE是一个功能强大的操作符,它可以让你选择你"喜欢"指定的行。百分号"%"可以被用来匹配任何可能的字符,它可以出现在指定字符的前面或者后面,例如:
    selectfirst,last,city
    fromempinfo
    wherefirstLIKE'Er%';
    以上这条SQL语句将会匹配任何名字以'Er'开始的名字,这里必须使用单引号。
    或者你也可以使用"%"在字符的前面,例如:
    selectfirst,last
    fromempinfo
    wherelastLIKE'%s';
    这条SQL语句将会匹配任何名字以's'结尾的名字。这个"%"的作用就跟DOS命令的"*"号很相似。
    select*fromempinfo
    wherefirst='Eric';
    以上的SQL语句只选择first名字为'Eric'的行
    这里有一个名为"empinfo"的表:
    firstlast
    idagecityprovince
    ZhangJiangsheng9512304323汕头广东
    HuangWeidong9812200123深圳广东
    LiSimin9811123434珠海广东
    ZhangSanmei9923221126厦门福建
    JiangDongsheng9800019028重庆四川
    LiuTongxin9723123131海南海南
    下面我们使用SELECT语句来进行一些检索:
    首先你可以从empinfo中检索出列为first、last、city的数据,语句如下:
    selectfirst,last,cityfromempinfo;
    这时候你将来得到以下的数据:
    first
    last
    id
    Zhang
    Jiangsheng
    95123043
    Huang
    Weidong
    98122001
    Li
    Simin
    98111234
    Zhang
    Sanmei
    99232211
    Jiang
    Dongsheng
    98000190
    Liu
    Tongxin
    97231231
    如果你使用以下语句:
    selectlast,city,agefromempinfo
    whereage>30;
    那就检索到以下的数据:
    last
    city
    age
    Simin
    汕头
    34
    Tongxin
    海南
    31
    这里有一个名为"empinfo"的表:
    first
    last
    id
    age
    city
    province
    Zhang
    Jiangsheng
    95123043
    23
    汕头
    广东
    Huang
    Weidong
    98122001
    23
    深圳
    广东
    Li
    Simin
    98111234
    34
    珠海
    广东
    Zhang
    Sanmei
    99232211
    26
    厦门
    福建
    Jiang
    Dongsheng
    98000190
    28
    重庆
    四川
    Liu
    Tongxin
    97231231
    31
    海南
    海南
    下面我们使用SELECT语句来进行一些检索:
    首先你可以从empinfo中检索出列为first、last、city的数据,语句如下:
    selectfirst,last,cityfromempinfo;
    这时候你将来得到以下的数据:
    first
    last
    id
    Zhang
    Jiangsheng
    95123043
    Huang
    Weidong
    98122001
    Li
    Simin
    98111234
    Zhang
    Sanmei
    99232211
    Jiang
    Dongsheng
    98000190
    Liu
    Tongxin
    97231231
    如果你使用以下语句:
    selectlast,city,agefromempinfo
    whereage>30;
    那就检索到以下的数据:
    last
    city
    age
    Simin
    汕头
    34
    Tongxin
    海南
    31
    若是使用:
    selectfirst,last,city,provincefromempinfo
    wherefirstLIKE'J%';
    将得到以下的数据:
    first
    last
    city
    Province
    Jiang
    Dongsheng
    重庆
    四川
    你如果想列出所有的数据,可以使用以下的语句:
    select*fromempinfo;
    这时候检索到的数据为:
    first
    last
    id
    age
    city
    province
    Zhang
    Jiangsheng
    95123043
    23
    汕头
    广东
    Huang
    Weidong
    98122001
    23
    深圳
    广东
    Li
    Simin
    98111234
    34
    珠海
    广东
    Zhang
    Sanmei
    99232211
    26
    厦门
    福建
    Jiang
    Dongsheng
    98000190
    28
    重庆
    四川
    Liu
    Tongxin
    97231231
    31
    海南
    海南
    如果你想查询first和last列中last的最后字符为'g'的数据,你可以使用:
    selectfirst,last,fromempinfo
    wherelastLIKE'%g';
    此时查询到的数据有:
    first
    last
    Zhang
    Jiangsheng
    Huang
    Weidong
    Jiang
    Dongsheng
    你还可以这样来从first、last和age列中来查询last中间有'sh'字符的数据:
    selectfirst,last,agefromempinfo
    wherelastLIKE'%sh%';
    结果为:
    first
    last
    age
    Zhang
    Jiangsheng
    23
    Jiang
    Dongsheng
    28
    最后,你还可以查询first为'Jiang'的数据:
    select*fromempinfowherefirst='Jiang';
    结果为:
    first
    last
    id
    age
    city
    province
    Jiang
    Dongsheng
    98000190
    28
    重庆
    四川
    好吧,为了让你对本节教程能更好的掌握,下面给你几个练习巩固巩固:
    1显示first和age列的每一个表中数据
    2显示first、last和city列中除了first=Jiang的所有表中的数据。
    3显示所有age大于30的列的数据。
    4显示first和last列中last是以"g"结尾的数据。
    5显示所有first为"Zhang"的列
    千万不要认为这些很简单而不作练习。因此这些都是基础,打好基础对于以后的学习是有帮助的。
    (4)创建表
    创建表
    这个createtable语句是用于创建一个新的表格。以下是一个简单创建表格语句的格式:
    createtable"tablename"
    ("column1""datatype",
    "column2""datatype",
    "column3""datatype");
    如果你想使用可选的约束,创建表格的格式为:
    createtable"tablename"
    ("column1""datatype"[constraint],
    "column2""datatype"[constraint],
    "column3""datatype"[constraint]);
    []=optional
    这里注意:你可以任意创建多列的表格,这个条件是可选的。
    为了更好的理解,下面举个例子:
    createtableemployee
    (firstvarchar(15),
    lastvarchar(20),
    agenumber(3),
    addressvarchar(30),
    cityvarchar(20),
    statevarchar(20));
    为了创建一个新表格,你可以在关键字createtable之后跟着表的名字,然后一个圆左括号”(”,然后是第一列的名字,再是这一列的数据类型,接着是任意的可选约束,最后是圆右括号”)”。确保在开始表格内容之前使用圆左括号并且在表的最后一列定义之后使用圆右括号是相当重要的。你还要保证每一个列定义之间有逗号分隔。最后在SQL语句结束时候加上分号";"。
    表格和列名必须以字母开头,第二个字符开始可以是字母、数字或者下划线,但是要保证名字的总长度不要超过30个字符。在定义表格和列名不要使用不要使用SQL预定的用于表格或者列名的关键字(比如"select"、"create"、"insert"等等),以避免错误的发生。
    数据类型是指在特定的列使用什么样数据的类型。如果一个列的名字为"Last_Name",它是用来容纳人名的,所以这个特定列就应该采用"varchar"(variable-lengthcharacter,变长度的字符型)数据类型。
    以下是几种常见的数据类型:
    char(size):固定长度的字符串型。Size是圆括号中指定的参数,它可以由用户随意设置,但是不能超过255个字节。
    varchar(size):变长度的字符串型。它的最大长度是由括号中的参数size设定的。
    number(size):数值型。最大数字的位数由括号中的参数size设置。
    date:日期数值型。
    number(size,d):数值型。它的最大数字的位数由括号中的参数sieze设定,而括号中的参数d是设置小数点的位数。
    什么是约束呢?当表被创建的时候,可以一列也可以多列共用一个约束。约束是一个跟列有关的基本准则,返回的数据必须遵循这个准则。下面举个例子,一个约束指定在一列中不能有两个记录共用一个数值。它们必须单独的。其它两个流行的约束是:"notnull",它设置了列不能留空白,即一定要有数据;以及"primarykey"(主键),主键约束定义了表中每一个记录(或行)的唯一标识。所有的这些将在以后的教程中再作进一步阐述。
    好吧,也许你已经有跃跃欲试的冲动了。作为本节练习,下面我们自己来设计和创建表格。
    你可以开始创建一个公司的雇员表格。你需要创建一个包含firstname、lastname、title、age和salary的表格。
    (5)插入数据到表
    Insert语句用于往表格中插入或者增加一行数据,它的格式为:
    insertinto"tablename"
    (first_column,...last_column)
    values(first_value,...last_value);
    []=optional
    简单举个例子:
    insertintoemployee
    (first,last,age,address,city)
    values('Luke','Duke',45,'2130BoarsNest','HazardCo');
    这里要注意:每一个字符窜都要用单引号括起来。
    为了往表中插入数据,要在关键字insertinto之后紧跟着表名,然后是左圆括号,接着是以逗号分开的一系列的列名,再是一个右圆括号,然后在关键字values之后跟着一系列用圆括号括起的数值。这些数值是你要往表格中填入的数据,它们必须与指定的列名相匹配。字符串笔译用单引号括起来,而数字就不用。在上面的例子中,'Luke'必须与列first相匹配,而45必须与列age相匹配。
    假如你想往employee表格中插入以下数据;
    ZhangWeiguo,28,北京601信箱,北京
    那么你要使用以下的SQL语句:
    insertintoemployee
    (first,last,age,address,city)
    values('Zhang','Weiguo',28,'北京601信箱','北京');
    (6)删除表
    删除表
    Droptable命令用于删除一个表格或者表中的所有行。其语法格式为:
    droptable"tablename"
    下面举个例子:
    droptableemployee;
    为了删除整个表(包括所有的行),可以使用droptable命令后加上tablename。Droptable命令跟从表中删除所有记录是不一样的:
    删除表中的所有记录是留下表格(只是它是空的)以及约束信息;而droptable是删除表的所有信息,包括所有行、表格以及约束信息等等。
    (7)更新记录
    更新记录
    Update语句用于更新或者改变匹配指定条件的记录,它是通过构造一个where语句来实现的。其语句格式如下:
    update"tablename"
    set"columnname"="newvalue"[,"nextcolumn"="newvalue2"...]
    where"columnname"OPERATOR"value"[and|or"column"OPERATOR"value"];
    []=optional
    下面举个例子来说明:
    updatephone_book
    setarea_code=623
    whereprefix=979;
    以上语句是在phone_book表中,在prefix=979的行中将area_code设置为623。
    updatephone_book
    setlast_name='Smith',prefix=555,suffix=9292
    wherelast_name='Jones';
    而以上的这段语句是在phone_book中,在last_name='Jones'的行中将last_name设置为'Smith',prefix为555,suffix为9292。
    updateemployee
    setage=age+1
    wherefirst_name='Mary'andlast_name='Williams';
    这段语句是在employee表中,在first_name='Mary'和last_name='Williams'的行中将age加1。
    作为每课一练,你在结束本教程之后要好好作以下的练习:
    1因为JonieWeber已经跟BobWilliams结婚,所以它需要将它的last名更新为Weber-Williams。
    2DirkSmith的生日是今天,所以他的年龄应该加1。
    3所有的秘书都叫做"AdministrativeAssistant".所以要将所有的标题标题都相应地修改。
    就作这几个练习,千万不可大意哟。
    (8)删除记录
    删除记录
    Delete语句是用来从表中删除记录或者行,其语句格式为:
    deletefrom"tablename"
    where"columnname"OPERATOR"value"[and|or"column"OPERATOR"value"];
    []=optional
    下面还是举个例子:
    deletefromemployee;
    这条语句没有where语句,所以它将删除所有的记录,因此如果没有使用where的时候,要千万小心。
    如果你只要删除其中一行或者几行,可以参考以下的语句:
    deletefromemployee
    wherelastname='May';
    这条语句是从emplyee表中删除lastname为'May'的行。
    deletefromemployee
    wherefirstname='Mike'orfirstname='Eric';
    这条语句是从emplyee表中删除firstname为'Mike'或者'Eric'的行。
    为了从表中删除一个完整的记录或者行,就直接在"deletefrom"后面加上表的名字,并且利用where指明符合什么条件的行要删除即可。如果你没有使用where子句,那么表中的所有记录或者行将被删除。
    (9)SELECT语句
    SELECT语句
    在上面的教程中已经有用到SELECT语句。在本节教程中将详细对它进行阐述。SELECT语句是SQL的核心,在你的SQL语句中可能用的最多的就是SELECT语句了。由于大量的选项可以用于SELECT语句,所以整个教程好象就是围这SELECT语句转。当我们构造SQL查询语句(利用了SELECT语句)的时候,认识所有的可能选项和最好的或者最有效率的方法来实现是很有用的。这个教程将为你提供这些技能。
    SELECT语句用于查询数据库并检索匹配你指定条件的选择数据。SELECT语句有五个主要的子句子你可以选择,而FROM是唯一必须的子句。每一个子句有大量的选择项、参数等等。这些子句将罗列在下面,而且它们每一个都将在以后的教程有更为详细的描述。
    以下是SELECT语句的格式:
    SELECT[ALL|DISTINCT]column1[,column2]
    FROMtable1[,table2]
    [WHERE"conditions"]
    [GROUPBY"column-list"]
    [HAVING"conditions]
    [ORDERBY"column-list"[ASC|DESC]]
    下面举个例子:
    SELECTname,age,salary
    FROMemployee
    WHEREage>50;
    上面的这个语句将从employee表中选择age大于50的所有的name、age和salary列的数值。
    注意:一定要在SQL语句末尾加上一个分号。这个分号提示SQL语句已经结束并准备被解释。
    以下的表格给出了各种比较运算符号:
    =
    等于
    >
    大于
    <
    小于
    >=
    大于等于
    <=
    小于等于
    <>
    不等于
    LIKE
    字符串比较测验
    举个例子吧:
    SELECTname,title,dept
    FROMemployee
    WHEREtitleLIKE'Pro%';
    上面的语句是从employee表中选择title是以'Pro'为开头的name、title和dept列中的所有行或者数值。
    另外ALL和DISTINCT也是SQL中的关键字,它们用于在你的查询结果中选择ALL(缺省)或者"distinct"或者单一记录。如果你想在指定的列中检索单一记录,你可以使用"DISTINCT"关键子。因为DISTNCT将会丢弃所有你在SELECT指定的列复制的记录,比如:
    SELECTDISTINCTage
    FROMemployee_info;
    这条语句将返回所有在employee_info表中单一的age数据。
    而ALL就将显示所有指定的类,包括所有的复制数据。在没有指定的时候,这个ALL关键字是缺省的。
    (10)合计函数
    合计函数
    所有的合计函数如下表所示:
    MIN
    返回一个给定列中最小的数值
    MAX
    返回一个给定列中最大的数值
    SUM
    返回一个给定列中所有数值的总和
    AVG
    返回一个给定列中所有数值的平均值
    COUNT
    返回一个给定列中所有数值的个数
    COUNT(*)
    返回一个表中的行数
    合计函数用于从SELECT语句中计算一个”返回列的数据”。它们是总结了所选数据列的结果。虽然它们需要"GROUPBY"子句(后面一个教程介绍),但是这些函数也可以在不用使用"GROUPBY"子句的情况被使用,比如:
    SELECTAVG(salary)
    FROMemployee;
    这条语句将返回单一的结果,它包含了从employee表中所有salary列数据的平均值。为了更好的理解,我们再举个例子:
    SELECTAVG(salary)
    FROMemployee;
    WHEREtitle='Programmer';
    以上这条语句将返回employee表中所有title列为'Programmer'的数据的平均值。
    下面的例子中使用的语句跟其它合计函数有点不用,因为没有一个类被指定给COUNT函数。这条语句实际上将返回employee表的行数,如下:
    SELECTCount(*)
    FROMemployees;
    最后给出本节教程的配套练习:
    1)作一个公司的销售表items_ordered,里面有price、product和amount。
    从items_ordered表中选择price最大的数据。这里提示:使用MAX函数。
    2)计算items_ordered表中的行数。
    (11)GROUPBY子句
    GROUPBY子句
    首先讲讲GROUPBY子句语法:
    SELECTcolumn1,SUM(column2)
    FROM"list-of-tables"
    GROUPBY"column-list";
    这个GROUPBY子句将集中所有的行在一起,它包含了指定列的数据以及允许合计函数来计算一个或者多个列。当然最好解释的方法是给出一个例子啦:
    假设我们将从employee表中搜索工资最高的列,可以使用以下的SQL语句:
    SELECTmax(salary),dept
    FROMemployee
    GROUPBYdept;
    这条语句将在每一个单独的部门中选择工资最高的工资。结果他们的salary和dept将被返回。
    (12)HAVING子句
    HAVING子句
    下面先给出HAVING子句的语法:
    SELECTcolumn1,SUM(column2)
    FROM"list-of-tables"
    GROUPBY"column-list"
    HAVING"condition";
    这个HAVING子句允许你为每一个组指定条件,换句话说,可以根据你指定的条件来选择行。如果你想使用HAVING子句的话,它应该处再GROUPBY子句之后。
    下面将以一个例子来解释HAVING子句。假设我们的employee表中包含雇员的name、departmen、salary和age。如果你想为每个部门中每个雇员选择平均工资的话,你可以使用下面的SQL语句:
    SELECTdept,avg(salary)
    FROMemployee
    GROUPBYdept;
    当然,如果你还想只计算和显示salary大于20000的平均工资的话,你还可以加上HAVING子句:
    SELECTdept,avg(salary)
    FROMemployee
    GROUPBYdept
    HAVINGavg(salary)>20000;
    (13)ORDERBY子句
    ORDERBY子句
    ORDERBY子句的语法为:
    SELECTcolumn1,SUM(column2)
    FROM"list-of-tables"
    ORDERBY"column-list"[ASC|DESC];
    []=optional
    ORDERBY是一个可选的子句,它允许你根据指定要orderby的列来以上升或者下降的顺序来显示查询的结果。例如:
    ASC=AscendingOrder–这个是缺省的
    DESC=DescendingOrder
    下面举个例子:
    SELECTemployee_id,dept,name,age,salary
    FROMemployee_info
    WHEREdept='Sales'
    ORDERBYsalary;
    这条SQL语句将从employee_info表中列dept等于'Sales'选择employee_id,、dept、name、age和salary,并且根据他们的salary按升序的顺序来列出检索结果。
    如果你想对多列排序的话,那么在列与列之间要加上逗号,比如:
    SELECTemployee_id,dept,name,age,salary
    FROMemployee_info
    WHEREdept='Sales'
    ORDERBYsalary,ageDESC;
    (14)组合条件和布尔运算符
    组合条件和布尔运算符
    以下的SQL语句中就含有组合条件:
    SELECTcolumn1,SUM(column2)
    FROM"list-of-tables"
    WHERE"condition1"AND"condition2";
    AND运算符可以在WHERE子句中连接两个或者多个条件。AND条件的两旁必须都为true(真),即两个条件都同时满足的时候,这些行才将被显示。
    当然,你也可以使用OR运算符,它也可以在WHERE子句中连接两个或者多个条件。但是,只要OR运算符两旁有一个为true的时候条件就满足了,因此行才会被显示。所以你使用OR运算符的时候,可以是OR运算符两旁只有一个为true或者两旁都为true。
    下面举个例子吧:
    SELECTemployeeid,firstname,lastname,title,salary
    FROMemployee_info
    WHEREsalary>=50000.00ANDtitle='Programmer';
    这条SQL语句是从employee_info表中选择salary大于等于50000.00并且title等于'Programmer'的列employeeid、firstname、lastname、title和salary。此时必须AND运算符两旁的条件都为真,行才会最为检索结果返回。如果其中有一个条件为假,那么就什么都没有显示。
    你可以使用圆括号将条件括起来,虽然它们也不一定是必须的,但是括起来看起来更清晰一些,这是一个编程习惯的问题。比如:
    SELECTemployeeid,firstname,lastname,title,salary
    FROMemployee_info
    WHERE(salary>=50000.00)AND(title='Programmer');
    下面再举个例子:
    SELECTfirstname,lastname,title,salary
    FROMemployee_info
    WHERE(title='Sales')OR(title='Programmer');
    这条语句将从employee_info表中选择title等于'Sales'或者等于'Programmer'的列firstname、lastname,title和salary。
    (15)IN和BETWEEN条件运算符
    IN和BETWEEN条件运算符
    下面是IN条件运算符的SQL语句:
    SELECTcolumn1,SUM(column2)
    FROM"list-of-tables"
    WHEREcolumn3IN(list-of-values);
    下面是BETWEEN条件运算符的SQL语句:
    SELECTcolumn1,SUM(column2)
    FROM"list-of-tables"
    WHEREcolumn3BETWEENvalue1ANDvalue2;
    实际上,IN条件运算符是一个设置成员测试运算符,也就是说,它用于测试是否一个数值处在IN关键字之后提供的数值之中。举个例子如下:
    SELECTemployeeid,lastname,salary
    FROMemployee_info
    WHERElastnameIN('Hernandez','Jones','Roberts','Ruiz');
    这条语句是从employee_info表中选择lastname等于Hernandez、Jones、Roberts或者Ruiz名字之一的列employeeid、lastname和salary。如果它在其中就将返回行。
    IN条件运算符可以使用混合条件来替代,比如你可以使用等号运算符或者使用OR运算符等等,但是结果是一样的,例如:
    SELECTemployeeid,lastname,salary
    FROMemployee_info
    WHERElastname='Hernandez'ORlastname='Jones'ORlastname='Roberts'ORlastname='Ruiz';
    你可以观察到,利用IN运算符时语句会更加简短并且容易读,特别是在你测试两个或者三个数值以上的时候尤为突出。
    当然你也可以使用NOTIN来在你的列表中排除行的。
    而BETWEEN条件运算符是用与测试一个数值是否处在BETWEEN关键字两边指定数值的中间,比如:
    SELECTemployeeid,age,lastname,salary
    FROMemployee_info
    WHEREageBETWEEN30AND40;
    这条SQL语句是从employee_info表中选择age处于30到40岁之间(包括30岁和40岁)的列employeeid、age、lastname和salary。
    这条语句同样可以不用BETWEEN运算符,而使用混合条件来替代,例如:
    SELECTemployeeid,age,lastname,salary
    FROMemployee_info
    WHEREage>=30ANDage<=40;
    当然,你也可以类似于NOTIN的方法,使用NOTBETWEEN来排除一些数据。
    SQL循序渐进(16)数学运算符
    数学运算符
    标准的ANSISQL-92支持下面四个基本的算术运算符:
    +
    加
    -
    减
    *
    乘
    /
    除
    %
    求余
    其中求余运算符决定除法的余数。这个运算符不是ANSISQL支持的,但是,绝大多数的数据库支持他。下面是一些有用的数学函数,因为可能要用到它,所以我这里要集中提一下。在ANSISQL-92中不支持这些函数,但是它们可能对于某些特殊的RDBMS是有效的。然而它们对于几个主要的数据库系统都是有效的。下面就说说这些数学函数吧:
    ABS(x)
    返回x的绝对值
    SIGN(x)
    当x为负数、零、正数的时候分别返回x的符号-1、0或者1
    MOD(x,y)
    返回x除以y的余数,跟x%y作用一样
    FLOOR(x)
    返回小于等于x的最大整数
    CEILING(x)或CEIL(x)
    返回大于等于x的最小整数
    POWER(x,y)
    返回x的y次方的数值
    ROUND(x)
    返回最接近于x的数
    ROUND(x,d)
    返回小数点数为4的接近于x的数
    SQRT(x)
    返回x的平方根
    下面举个例子:
    SELECTround(salary),firstname
    FROMemployee_info
    上面这条语句将从employee_info表中选择salary最接近的数以及firstname列。
    (17)JOIN子句
    JOIN子句
    不知你有没有发现直到现在我们利用SELECT语句来检索的时候只能从一个表中进行。如果你想从两个表或者更多的表中进行检索,该怎么办呢?好在我们可以使用SQL和关系数据库系统的一个很有用的特性,即"Join"。为了简单说明,实际上"Join"就是使得关系数据库系统相关的东东。"Join"允许你从两个表或者更多的表连接数据进行数据检索,而只需要利用一个SELECT语句。如果在FROM关键字之后有多个表的话,"Join"可以在SQLSELECT语句中识别它们。
    下面举个例子:
    SELECT"list-of-columns"
    FROMtable1,table2
    WHERE"search-condition(s)"
    "Join"
    通过示范当你只处理一个表的时候会发生什么事情可以使得"Join"的解释更简单,所以这里我没有使用"Join"。这个单一的数据库有事也被称为"flattable"(平表)。现在你有一个表的数据库用来检索所有顾客的信息以及他们从你的商店买了什么,下面就是这个表的所有列:
    
    每次一个新行被插入到表中,所有的列都将被更新,这样就导致了不必要的”多余数据”。比如,每次Jenny买东西,下面的行都将被插入到表中:
    
    为了避免”多余数据”,一个最好的方法:让数据库有两个表:其中一个用来对顾客保持跟踪;另外一个用来对他们买什么东西保持跟踪。即有"Customer_info"表和"Purchases"表:
    "Customer_info"表为:
    customer_number
    firstname
    lastname
    address
    city
    state
    zip
    "Purchases"表为:
    customer_number
    date
    item
    price
    现在开始,不管顾客什么时候进行重复的购物,只有第二个表"Purchases"需要更新。这样我们就减少了多余的数据,也就是说我们规格化了这个数据库。
    你仔细点就会发现两个表中还是有一个"cusomer_number"列是相同的。这个列包含了单独的顾客号,它将用来JOIN(连接)两个表。下面举个例子来使用这两个表,假如你想搜索顾客的名字以及他们所买的东西,你可以使用以下的语句来实现:
    SELECTcustomer_info.firstname,customer_info.lastname,purchases.item
    FROMcustomer_info,purchases
    WHEREcustomer_info.customer_number=purchases.customer_number;
    特殊的"Join"有为"InnerJoin"或者"Equijoin",这是一个最常见的"Join"类型,以后我们经常用使用到或者看到。
    这里要注意每列总是在表名之前,这却也不是必需的。这是一个好的练习对于帮助你澄清列后面跟着表的认识有很大帮助。如果两个表之间有一个相同的列,它就是必须的。我这里推荐在使用JOIN的时候最好在所有列之后加上表名。
    注意;上面描述的这个语法将在绝大多数的数据库系统起作用,本教程的也是一样。但是结果你会发现你上面的语句并不起作用,请仔细检查一下吧。
    当然你可以试一试修改以上的代码,你可以使用JOIN(ANSISQL-92语法规范中的INNERJOIN):
    SELECTcustomer_info.firstname,customer_info.lastname,purchases.item
    FROMcustomer_infoINNERJOINpurchases
    ONcustomer_info.customer_number=purchases.customer_number;
    再举另外一个例子:
    SELECTemployee_info.employeeid,employee_info.lastname,employee_salesission
    FROMemployee_info,employee_sales
    WHEREemployee_info.employeeid=employee_sales.employeeid;
    这个例子将从employee_info和employee_sales表中选择当employee_info表的employeeid等于employee_sales表的employeeid的employeeid、emplyee_info表中lastname以及employee_sales表中的comission数值。
    从上面的例子中可以发现利用JION的语句比价简练。既然有这样的有点,我们何乐而不为呢?
    (18)索引
    索引
    索引允许DBMS更快地访问数据。系统创建了这个内部地数据结构(即索引),它导致当查询以列为索引的时候搜索行,这样查询会快得多。这个索引对于给定列索引数值的时通知DBMS找到表中某一行,这有点象书的索引,它告诉你对于给定的字你能找到哪一页。下面让我们在AntiqueOwners列中为OwnerID创建索引:
    CREATEINDEXOID_IDXONANTIQUEOWNERS(OWNERID);
    下面语句是为名字创建所以:
    CREATEINDEXNAME_IDXONANTIQUEOWNERS(OWNERLASTNAME,OWNERFIRSTNAME);
    为了删除索引,你可以利用DROP:
    DROPINDEXOID_IDX;
    就象前面教程中,我们也可以"drop"(删除)一个表。上面第二个例子中,是在两列上创建索引的。
    有些DBMS不强迫要求主键,换句话说就是,类的唯一性不会自动强制。这是什么意思呢,好象听起来云里雾里的。好吧,再给你举个例子,如果你象插入另外一行到AntiqueOwners表中,比如这个OwnerID是02,有些系统可以让你这样做即使我们要求所有行的数值都要是不同的。为了避免两行有相同的值,我们有一种方法来克服,就是在列上创建唯一的索引,而在这个列上我们需要它成为主键,这样就可以系统不会出现复制的情况:
    CREATEUNIQUEINDEXOID_IDXONANTIQUEOWNERS(OWNERID);
    (19)DISTINCT和排除复制
    DISTINCT和排除复制
    假如你象列出所有买过古董的ID和名字,很明显,你可能会将所有的顾客都列出来而没有考虑有些顾客是买过多讲古董的,所以这时你会发现有些数据是重复的。这就意味着你需要通知SQL来排除复制的行,而不管这个顾客买过多少个古董只需要列出一次即可。为了实现这个目的,你可以使用DISTINCT关键字。
    首先我们需要为AntiqueOwners表来一个equijoin以得到顾客的LastName和First的详细数据。但是,你要考虑到Antiques表中的SellerID列是AntiqueOwners表的一个外码,所以顾客只能在AntiqueOwners表列出ID和名字的行才被列出。我们还想在列的数据中排除SellerID复制的发生,所以我们要在发生重复的列上使用DISTINCT。
    为了防止复制的发生,我们还想将LastName以字母顺序排列,然后在按字母顺序排列FirstName最后排列OwnerID,因此我们还必须使用ORDERBY子句,具体语句如下:
    SELECTDISTINCTSELLERID,OWNERLASTNAME,OWNERFIRSTNAME
    FROMANTIQUES,ANTIQUEOWNERS
    WHERESELLERID=OWNERID
    ORDERBYOWNERLASTNAME,OWNERFIRSTNAME,OWNERID
    在这个例子中,因为每个人都买都一个件古董,所以我们将Lasname以字母顺序列出所有的古董拥有者。
    (20)Aliases、In以及子查询
    Aliases、In以及子查询
    在本节教程中,我们将要介绍Aliases、In以及子查询的用法。首先我们看一下一个查询语句,它搜索所有已经定货的顾客的LastName以及他们定什么货,语句如下:
    SELECTOWN.OWNERLASTNAMELastName,ORD.ITEMDESIREDItemOrdered
    FROMORDERSORD,ANTIQUEOWNERSOWN
    WHEREORD.OWNERID=OWN.OWNERID
    ANDORD.ITEMDESIREDIN
    (SELECTITEM
    FROMANTIQUES);
    这条查询语句的结果为:
    LastNameItemOrdered
    ---------------------
    SmithTable
    SmithDesk
    AkinsChair
    LawsonMirror
    下面好好解释一下上面的这条语句:
    "LastName"和"ItemOrdered"给出了报告的数据头。
    OWN&;ORD是aliases(别名),它们使用在FROM子句中,可在它们的后面加一个点号再加列名就可以进行查询了。这样做就避免了模棱两可的情况,特别是在equijoinWHERE子句中当两个列都名为OwenerID的时候,而点号就通知SQL我们使用是两个不同表的不同OwnerID。
    这里要注意,在FROM子句中Orders表被首先列出,并且确保AntiqueOwners表只用于详细的信息(LastName)。更为重要的,在WHERE子句中的AND强迫In子查询被调用("=ANY"or"=SOME"都等价于使用IN)。但这到底做了些什么呢?当这个子查询完成了,它就返回Antiques表的所有Items因为这里没有WHERE子句。然后,对于从Orders表列出的行,ItemDesired必须在从Antiques表中返回的Items列表中,然后在定货可以有另外的拥有者填写的情况下列出一个item。你可以想想这个方法:子查询从Orders表中的每一个ItemDesired被比较中返回一系列的Items;如果ItemDesired是在从Antiques表中返回的,那么条件才为真。
    (21)更多的子查询
    更多的子查询
    我们可以使用在SELECT查询语句中再包括一个SELECT子查询语句。举个例子吧,首先我们列除所有购买贵重物品的顾客,贵重物品的标准是比所有卖出的物品价钱的平均值多100元的物品。具体语句如下:
    SELECTOWNERID
    FROMANTIQUES
    WHEREPRICE>
    (SELECTAVG(PRICE)+100
    FROMANTIQUES);
    上面子查询语句是计算物品的平均价格再加100元,并搜索所有在ANTIQUES表中PRICE大于这个数值的OWNERID。这里你可以使用DISTINCTOWNERID来排除复制的现象。
    下面的语句列出了所有在AntiqueOwners表中的有买过物品的人的LastName:
    SELECTOWNERLASTNAME
    FROMANTIQUEOWNERS
    WHEREOWNERID=
    (SELECTDISTINCTBUYERID
    FROMANTIQUES);
    这个子查询返回了一系列的顾客,当且仅当物品拥有者的ID出现在子查询的列表中,古董的拥有者的LastName才会显示出来。
    为了更新这个例子,我们假设有一个买过bookcase的顾客,他的FirstName在数据库中出错了,应该为John:
    UPDATEANTIQUEOWNERS
    SETOWNERFIRSTNAME='John'
    WHEREOWNERID=
    (SELECTBUYERID
    FROMANTIQUES
    WHEREITEM='Bookcase');
    上面的语句中的子查询首先搜索买过bookcase的顾客的BuyerID,然后在外层的查询中来更新他的FirstName。
    (22)EXISTS和ALL
    EXISTS和ALL
    EXISTS使用了一个子查询作为条件,只有当子查询返回行的时候这个条件才为真,如果子查询不返回任何的行条件就为假。如果商店在处理Chair的时候,有个顾客想看看所有拥有者的列表,就可以使用EXSIST,语句如下:
    SELECTOWNERFIRSTNAME,OWNERLASTNAME
    FROMANTIQUEOWNERS
    WHEREEXISTS
    (SELECT*
    FROMANTIQUES
    WHEREITEM='Chair');
    如果在Antiques列中有Chair,那么子查询就会返回一行或者多行,就使得EXISTS子句为真,然后让SQL列出拥有者来。如果没有搜索到Chair,则没有行被返回,条件就为假。
    ALL是另外一个不寻常的关键字,因为ALL查询通常可以用不同的方法来进行,并且可能是一种更为简单的方法。举个例子来说明吧:
    SELECTBUYERID,ITEM
    FROMANTIQUES
    WHEREPRICE>=ALL
    (SELECTPRICE
    FROMANTIQUES);
    上面这条语句将返回最高价格的Item以及它的买方。子查询返回了Antiques表中的所有的Price列,而外层的查询逐行查询Antiques表,并且如果它的Price大于等于(或者ALL)列中的Prices,它就会被列出,它就是最好价格的Item。这里必须使用">="的原因是最高价格的Item要等于列表中的最高价格,因为这个Item在Price列中。
    (23)UNION和外部连接
    UNION和外部连接
    有些时候,你可以想一起看多个查询的结果、组合它们的输出,你可以使用UNION关键字。为了合并以下两个查询的输出:显示所有买方的ID和已经有定货的顾客,你可以使用以下语句:
    SELECTBUYERID
    FROMANTIQUEOWNERS
    UNION
    SELECTOWNERID
    FROMORDERS;
    这里要注意SQL要求SELECT的列表必须匹配,即列于数据类型匹配。在本例子中,BuyerID和OwnerID都是相同的数据类型,同为Interger(整型)。同时还有一提的是,SQL但使用UNION的使用会进行自动复制排除。而在单一的查询中,你就必须使用DISTINCT。
    OuterJoin(外部连接)通常是在JOIN查询被联合,而行没有包括到JOIN中的时候使用,特别是在常量文本"flags"被包括的时候尤为有用。下面我们看看这个查询先:
    SELECTOWNERID,'isinbothOrders&;Antiques'
    FROMORDERS,ANTIQUES
    WHEREOWNERID=BUYERID
    UNION
    SELECTBUYERID,'isinAntiquesonly'
    FROMANTIQUES
    WHEREBUYERIDNOTIN
    (SELECTOWNERID
    FROMORDERS);
    第一个查询做了一个连接以列出两个表中的每个owener,并且在ID后面放置一个标记线来重复引用。这个UNION合并了这个列表以及以下第二个的列表。第二个列表是列出不是在Orders表的ID,这样就产生了在JOIN查询之外的ID列表,它是利用引用标签列出的。这可能是一种最容易的方法来产生这个列表。
    这个概念对于主键跟外码有关的状况是很有用的,但是有些主键的外码值是NULL。比如,在一个表中,主键是salesperson,而在其它的表中主键是customers,并且它们的salesperson列在相同的行。然而,如果salesperson没有customers的时候,这个人的名字就不会出现在customer表中。如果所有salespersons的列表要显示出来,那么就要外部连接了。
    (24)嵌入SQL
    嵌入SQL
    为了更好的理解嵌入SQL,本节利用一个具体例子来说明。嵌入SQL允许程序连接数据库并且包括SQL代码到程序中,这样在程序中就可以对数据库进行使用、操作以及处理数据等等。以下是用C语言编写的使用嵌入SQL的例程,它将打印一个报告;这个程序必须在普通的编译之前先预编译SQL语句。嵌入SQL对于不同系统是不一样的,所以在不同的系统中对以下的程序稍作修改,特别是变量的声明以及过程记录等。在嵌入SQL时,考虑网络、数据库管理系统、操作系统是相当重要的。
    以下是详细的代码:
    #include
    /*以下这部分是声明主机变量,它将使用于程序中*/
    EXECSQLBEGINDECLARESECTION;
    intBuyerID;
    charFirstName[100],LastName[100],Item[100];
    EXECSQLENDDECLARESECTION;
    /*以下包括SQLCA变量,它可以用来进行错误检查*/
    EXECSQLINCLUDESQLCA;
    main(){
    /*以下连接数据库*/
    EXECSQLCONNECTUserID/Password;
    /*以下是连接数据库并检查是否有错误产生T*/if(sqlca.sqlcode){
    printf(Printer,"Errorconnectingtodatabaseserver.\n");
    exit();
    }
    printf("Connectedtodatabaseserver.\n");
    /*下面声明一个"Cursor"。它将在查询结果多于一行的时候使用*/
    EXECSQLDECLAREItemCursorCURSORFOR
    SELECTITEM,BUYERID
    FROMANTIQUES
    ORDERBYITEM;
    EXECSQLOPENItemCursor;
    /*你可以在这里还可以加入另外一些错误检查的内容,这里就省略了*/
    /*当这个CURSOR没有数据,sqlcode将被产生以允许我们退出循环。这里注意,为了简单起见,我们使程序遇到错误的时候就退出任何的sqlcode。*/
    EXECSQLFETCHItemCursorINTO:Item,:BuyerID;
    while(!sqlca.sqlcode){
    EXECSQLUPDATEANTIQUES
    SETPRICE=PRICE+5
    WHEREITEM=:ItemANDBUYERID=:BuyerID;
    EXECSQLSELECTOWNERFIRSTNAME,OWNERLASTNAME
    INTO:FirstName,:LastName
    FROMANTIQUEOWNERS
    WHEREBUYERID=:BuyerID;
    printf("%25s%25s%25s",FirstName,LastName,Item);
    EXECSQLFETCHItemCursorINTO:Item,:BuyerID;
    }
    /*关闭CURSOR,提交变化并退出程序。*/
    EXECSQLCLOSEDataCursor;
    EXECSQLCOMMITRELEASE;
    exit();
    }
    
  • 上一篇资讯: SQL电子书
  • 下一篇资讯: SQL测验
  • 设为首页 | 加入收藏 | 网学首页 | 原创论文 | 计算机原创
    版权所有 网学网 [Myeducs.cn] 您电脑的分辨率是 像素
    Copyright 2008-2020 myeducs.Cn www.myeducs.Cn All Rights Reserved 湘ICP备09003080号 常年法律顾问:王律师