结构化查询语言SQL
一、概述SQL是结构化查询语言StructuredQueryLanguage)的缩写,是广泛使用的数据库标准语言。SQL语言的主要功能:数据查询数据定义数据操纵数据控制SELECTCREATE、DROP、ALTERINSERT、UPDATE、DELETEGRANT、REVKOE
SQL语言的主要特点:一体化,非过程化,简洁易用,面向集合的操作方式,两种使用方式自含式语言独立使用,嵌入式语言嵌入到其它高级语言中以程序方式
使用)。二、SQL数据查询最基本的查询命令格式为:SELECT<字段及字段运算列表>FROM<数据源列表>常用子句有:条件子句:WHERE……排序子句:ORDERBY……分组子句:GROUPBY……筛选分组条件:HAVING输出去向子句:TO/INTO……一、简单查询【例1】从职工中查询所有工资值。【说明】结果中有重复值,如果要去掉重复值
只需指定DINSTINCT。用selectdistinct工资from职工,观察此次运算结果与上次的不同【例2】从职工表中查询职工中的所有信息。【说明】“*”号是通配符,代表所有的字段。二、条件查询:从表或视图里选取满足条件的条件查询:记录WHERE<条件表达式>[AND|OR<条件表
达式>……]【例3】从职工表中检索工资多于1230的职工。【例4】从职工表中检索哪些仓库有工资多于1230的职工。select仓库号from职工where工资>=1230【例5】从职工表中查询出在仓库“WH1”或者“WH2”工作,并且工资少于1250的职工。
三、几个特殊的运算符1、判断范围:BETWEEN…AND、判断范围WHERE<列>BETWEEN<范围初值>
AND<范围终值>等价于:列值>=范围初值AND列值<=范围终值【例6】从职工表中查询工资在1220到1240之间的职工信息。【例7】从职工表中查询工资不在1220到1240之间的职工信息。2、判断匹配:LIKE——模糊查询、判断匹配:——模糊查询——【格式】WHERE字符型列LIKE字符串【功能】与指定值相匹配的字符型记录进入结果集,查询中可以使用通配符进行部分匹配查询。
【说明】字符串常量中可以使用两种通配符:%:表示任意知长度的字符串,类似于操作系统中的“*”号_:表示任意一个字符西文,中文)【例8】从供应商表中检索出供应商名中含电子两字的供应商信息3、不等于、NOT,!=,<>
【例9】从供应商表中查询不在北京的全部供应商的信息。
四、简单计算查询简单计算查询表1SQL数值函数及其功能函数名称功AVGSUMCOUNTMAXMIN能
按列计算字段值的平均值按列计算字段值的总和按列统计记录个数求一列中的最大值求一列中的最小值
【例10】从供应商表中统计供应商所在地的数目总数selectcount(distinct地址)as个数from供应商【例11】从职工表中统计所有职工工资总和selectsum(工资)as总工资from职工
【例12】从职工表中统计在WH2仓库工作的职工的最高工资selectmax(工资)as最高工资from职工where仓库号="WH2"七、筛选前若干条记录SELECT[TOP<表达式>[PERCENT]]<输出列列表>;ORDERBY<排序子句>【功能】指定在查询结果中,只选取前面指定个数或指定百分比的记录数。【例18】从职工表中查询工资最高的三位职工。【例19】从books中查询及格最低的30%的图书信息。selectop30percent*frombooksorderby价
格五、分组与统计查询GROUPBY子句可以实现按指定列的值进行分组,列值相等的记录为一组;同时,GROUPBY子句可以与任何数值计算函数求和、求平均、统计等)一起使用。【格式】GROUPBY<列名>[,<列名>…];[HAVING<筛选条件>]【功能】GROUPBY<列名>[,<列名>…]把查询结果中的记录按一个或多个列的值分组;[HAVING<筛选条件>]用于指定对各个分组再次筛选,并将满足条件的分组送入结果集。【说明】HAVING必须与GROUPBY一起使用。
1.分组统计.【例13】从职工表中统计每个仓库的职工的平均工资。2.分组筛选.若在分组后还要按照一定的条件对分组进行筛选,只把满足条件的分组送入结果集,则需使用HAVING子句。【例14】求至少有两个职工的每个仓库的平均工资。select仓库号,avg(工资as平均工资from工资)工资职工groupby仓库号havingcount(*)>=2【说明】1.GROUPBY子句按仓库号分组,对每一组每个职工的工资)使用函数COUNT和AVG(工(*)资)分别进行统计,得到每个仓库的人数和平均
工资。HAVING子句在所有分组中去掉不满足至少有两个职工的组。2.WHERE子句与HAVING子句的区别当在一个SQL查询中同时使用WHERE子句,GROUPBY子句和HAVING子句时,其顺序是WHERE、GROUPBY、HAVING。WHERE与HAVING子句的根本区别在于作用对象不同。记录进行筛选,在GROUPBY之前WHERE对记录记录执行HAVING在分组分组里筛选,在GROUPBY之后执分组行补充:单表查询综合例子:利用成绩表查询至少有2门课成绩在80分以上的同学信息出来本命令的执行过程是一定要理解,记忆本命令的执行过程是一定要理解,
1)FROM成绩
&;&;取出整个选课表
2)WHERE成绩>=80&;&;取出想要的记录3)GROUPBY&;&;晒出的结果在按分组实现每位学生一组4)HAVINGCOUNT(*)>=2&;&;记录条数大于3的组,保留在结果集3.多字段分组.【格式】GROUPBY<列名>[,<列名>…];表中统计各部门,【例15】从SELL表中统计各部门,各年度的从平均销售额和平均工资额六、输出结果的排序ORDERBY<列名>[ASC/DESC][,<列
名>[ASC/DESC]…]]选项ASC为升序这是默认值,可以不写;
列名可以用列数代替。【例16】从职工表中按职工的工资升序查询所有职工的信息。【例17】从职工表中先按仓库号,再按工资排序输出全部职工的信息。*:若在一个查询中,分组,条件,排序都要用:若在一个查询中,分组,条件,到,默认顺序是select,然后是from,其次是然后是,where,,然后是groupby[having],最后是order最后是by八、简单的联接查询简单的联接查询方法1:使用条件子句WHERE;方法2:使用连接关键字JOIN。1、使用WHERE建立连接、【格式】SELECT<输出列列表>;FROM<表1>,<表2>[……];
WHERE<连接条件>[AND筛选条件]【例20】从职工表和仓库表中查询工资多于1230元的职工号号和他们所在的城市。【说明】FROM之后的多个关系含有相同的当属性名时,这时必须用关系前缀指明属性所属的关系。“.”前面是关系名,后面是属性名。【例21】从职工表和仓库表中查询工作在面积大于400的仓库的职工号以及这些职工工作所在的城市。2、使用连接关键字JOIN建立连接、【格式】SELECT<输出列列表>;FROM<表名>;INNER/LEFT/RIGHT/FULLJOIN<表名>;ON<连接条件>…【功能】进行多表连接查询。
【说明】JOIN连接具体分为以下几种:INNERJOIN:内连接,两个表中都有的关键字值,其记录才会进入结果集,此为默认值;其功能类似于WHERE连接;LEFT[OUTER]JOIN:左外)连接,包含左表中全部记录和右表中与之匹配的记录,左表中不满足条件的那一部分记录对应部分为NULL。RIGHT[OUTER]JOIN:右外)连接,包含右表中全部记录和左表中与之匹配的记录,右表中不满足条件的那一部分记录对应部分为NULL。FULL[OUTER]JOIN:全连接,两侧表中不管是否满足连接条件都全部进入结果集,此时不
满足连接条件而缺乏数据的记录对应部分为NULL;连接类型在FROM子句中指定,连接条件用ON选项指定,[OUTER]可以省略。【例22】从职工表和仓库表中求北京和上海的仓库职工的工资总和。selectsum(工资)as总工资from职工innerjoin仓库on职工.仓库号=仓库.仓库号;where城市="北京"or城市="上海"【例23】从职工表和仓库表中求所有职工的工资都多于1210元的仓库的平均面积。【例24】从rate_exchange表和currency_sl两表中查询所有人持有外币的外币名称和持有数量,【例25】从rate_exchange表和currency_sl两
表中查询林诗因持有外币的外币名称和持有数量,并按持有数量进行降序排列显示【例26】sell和dept中关联查询各个部门的从部门名以及在各个年度的平均销售额,平均工资额以及平均利润【例27】在上题的基础上,检索网络产品部的信息情况【例28】从使用零件和零件信息中统计S1项目所用零件的金额总和【例29】从books和authors中统计每个作者的,所编书籍的书名,以及出版单位和价格,并按价格降序排列显示【例30】从books和authors中统计出版书籍在3本以上的作者和电话【例31】统计在经济科技出版社出书最多的作
者selecttop1作者,count(*)as本数frombooksinnerjoinauthorsonbooks.作者编号=authors.作者编号where出版单位="经济科学出版社"groupbyauthors.作者编号orderby2desc【例32】从student,course,score三表中关联查询所有学生的,选课的课程名以及该门课程的成绩并按升序排列显示【例33】从项目信息,使用零件,零件信息中查询所有项目的项目名,所用零件的零件名称,数量,单价信息九、别名与自联接1、别名:在联接操作中经常需要使用关系名,为了避免书写麻烦,SQL允许为关系名定义别
名:<关系名>[AS]<别名>2、自联接:主要用于同一个表中数据的比较【例34】从employee表中筛选所有员工的姓名以及相应管理者的e1.员工,e2.,e2.selecte1.as员工,e2.as管理者;理者;employeefromemployeease1innerjoinemployeease1.管理者号=e2.职工号管理者号=e2.e2one1.管理者号=e2.职工号十、嵌套查询(重点,难点)嵌套查询(重点,难点)就是SELECT语句(父查询)的WHERE子句中包含另一个SELECT语句(子查询)。在执行时,分两步:先执行子查询得到查询的结果,再把结果带入父查询执行。
35】【例35】从供应,零件中筛选出用了绿颜色零件的工程号和数量子查询语法1、WHERETEST_EXPROP(子查询)2、WHERETEST_EXPR[NOT]IN(子查询)3、WHERETEST_EXPROPALL(子查询)4、WHERETEST_EXPROPANY(子查询)5、WHERE[NOT]EXISTS(子查询)
一:比较子查询的值WHERETEST_EXPROP(子
查询),如果子查询返回的值满足同TEST_EXPR的比较,对比条件的值为真,则筛选出来【例10】从职工表中查询和职工E4挣同样工资的所有职工。【例25】从职工表中查询所有比E6工资高的
职工的信息。
【例36】BOOKS表中筛选价格超过所有图书平从均价格的图书信息【例37】BOOKS表中筛选出价格大于所有高等从教育出版社出版图书价格的图书信息【例38】xuesheng和chengji中筛选每门课程上从的成绩都大于等于所有同学在该门课程上的平均分的同学的和selectxuesheng.,fromxuesheng;innerjoinchengjionxuesheng.=chengji.where数学>(selectavg(数学)fromchengji);and英语>(selectavg(英语)fromchengji);and信息技术>(selectavg(信息技术)fromchengji)注意:该种嵌套查询要求子查询必须返回唯一值注意:该种嵌套查询要求子查询必须返回唯一值
二:使用IN测试集合成员资格WHERETEST_EXPR[NOT]IN(子查询)【例8】从仓库和职工中查询哪些城市至少有一个仓库的职工工资为1250元。【例9】从仓库和职工中查询所有职工的工资
都多于1230元的仓库的信息。【例39】从供应和零件中选出所有用红颜色零件的项目信息select工程号,数量from供应where零件号in(select零件号from零件where颜色="红")
注意:子查询的SELECT子句只可以包含一个表达式或列名,子查询必须返回一列零行或多行,子查询返回超过一列会引发错误)如果TEST_EXPR。等于子查询返回的任一值,IN条件结果为真【例40】从零件和供应表中查询工程号J4所使用的零件的零件名,颜色和重量【例41】从BOOK,LOANS,BORROWS中筛选出田亮所借图书的书名,作者和价格select书名,作者,价格frombook;where图书登记号in(select图书登记号fromloans,borrowswhereloans.借书证号=borrows.借书证号and="田亮")【例42】从零件信息,使用零件,项目信息中查询与项目号S1的项目所使用的任意一个零件相同的
项目号,项目名,零件号和零件名称,结果按项目号降序排列select项目信息.项目号,项目名,零件信息.零件号,零件名称;from零件信息innerjoin使用零件on零件信息.零件号=使用零件.零件号innerjoin项目信息;on使用零件.项目号=项目信息.项目号;where使用零件.零件号in(select零件号from使用零件where项目号="s1")【例43】从books,authors中查询未出版书籍的作者信息三:使用ALL比较所有子查询的值WHERE
TEST_EXPROPALL(子查询)ALL跟在=,>,<,<>,与子查询的结果中的每一项均进行比较,全部都成立的时候WHERE条件表达式为真
【例44】BOOKS中筛选出所有比黄河出版社出从版图书都低的图书信息四:使用ANY比较某些子查询的值WHERE
TEST_EXPROPANY(子查询)(ANY可以用SOME表示)如果子查询中的某个。(至少一个)值满足ANY条件,则WHERE条件表达式为真【例45】从BOOKS中查找至少有一本书价格比清华大学出版社所出图书价格高的出版单位五:使用EXISTS检测存在性已经使用操作符IN,ALL和ANY对一个特定的检测值与子结果进行比较,EXISTS和NOTEXISTS不比较值,而是在子查询结果中确定存在或不存在行WHERE[NOT]EXISTS(子查询):如果子查询返回一行或多行,EXISTS测试的结果就为真。思考下列语句的查询结果和执行过程。SELE*FROM职工WHEREEXISTS;
(SELE*FROM职工WHERE仓库号=”WH3”)SELE*FROM职工WHERENOTEXISTS;(SELE*FROM职工WHERE仓库号=”WH3”)【例46】从职工和仓库表中查询那些仓库中还没有职工的仓库的信息。仓库号;SELE*FROM仓库WHERE仓库号;NOTIN(SELE仓库号FROM职工)职工)SELE*FROM仓库WHERENOTEXISTS;仓库号=仓库.(SELE*FROM职工WHERE仓库号=仓库.仓库号)按照惯例,子查询中的SELECT子句是用子查询中的SELECT*来检索出所有的列,因为EXISTS来检索出所有的列,来检索出所有的列只是简单检测满足子查询条件的行是否存在,
列出具体列名师没有必要的,与行中的实际值是多少也并无关系十一、十一、嵌套与自连接46】【例46】从订购单中列出每个职工经手的具有最高总金额的订购单信息
select*from订购单asawhere总金额=(selectmax(总金额)from订购单asbwherea.职工号=b.职工号)【例47】查询score表中每门课程得分最高分的
学生和成绩
select*fromscoreasawherea.成绩=(selectmax(b.成绩)fromscoreasbwherea.课程编号=b.课程编号)