• 数据库数据查询


    什么是查询呢?

    查询是对已有表中的数据按照某种条件进行筛选,将满足条件的数据筛选出来形成一个新的记录集进行显示,也称为查询结果记录集,

    这个记录集的结构与表的结构类似,由行和列组成,但它并不是真正存放在数据库中的表,  而是一种存放在计算机内存中的虚拟表。

    若省略查询条件,则返回数据源中的所有记录行。

    查询是查找和筛选功能的扩充,它不但能实现数据检索,而且可以在查询过程中进行计算、合并不同数据源的数据,甚至可以添加、更改或删除基本表中的数据。

    查询的数据源

    查询的数据源(也称为“记录源”,RecordSource)是存放在数据库中的基本表或已经创建好的视图,可以有一个或多个数据源。

    若是多个数据源,则需指定这些数据源之间的关联关系,以保证查询结果的正确性

    查询的结果

    查询的结果只有在运行查询时才会产生,因此也称为动态结果记录集,这个结果集的显示可以通过前面我们所学过的视图来实现。

    数据查询是数据库的核心操作。SELECT语句是SQL语言中功能最强大的语句。

    语句格式

    SELECT [ALL|DISTINCT] <目标列表达式> [,<目标列表达式>] .... 

    FROM <表名或视图名>[,< 表名或视图名> ] .... (SELECT语句)[AS]<别名>

    [WHERE<条件表达式>]

    [GROUP BY<列名1>[ HAVING<条件表达式> ] ]

    [ ORDER BY <列名2> [ ASC|DESC ] ] ;

    SELECT子句:指定要显示的属性列

    FROM子句:指定查询对象(基本表或视图)

    WHERE子句:指定查询条件

    GROUP BY子句:对查询结果按指定列的值分组,该属性列值相等的元组为一个组。通常会在每组中作用聚集函数。

    HAVING短语:只有满足指定条件的组才予以输出

    ORDER BY子句: 对查询结果表按指定列值的升序

    单表查询

    查询仅涉及一个表,是一种最简单的查询操作

    1.选择表中的若干列(列查询)

    2.选择表中的若干元组(行查询)

    3.对查询结果排序

    4.使用聚集函数

    单表查询语句基本格式:

    [USE 数据库名称]

    select 目标列表达式 [......n]

    from 表名

    where 条件(表达式)

    [ORDER BY排序条件]

    列查询

    1.查询指定列

    例:查询全体学生的学号和姓名

    select sno,sname
    from student

    2.查询全部列

    例:查询全体学生的详细记录

    select sno,sname,sgender,sage,sdept
    from student
    
    select *
    from student

    3.查询经过计算的值

    SELECT子句的<目标列表达式>为表达式(算术表达式、字符串常量、函数、列别名)

    例:查询全体学生的姓名、出生年份和所在系,要求用小写字母表示所有系名,并使用列别名改变查询结果的列标题

    select sname as 'name',year(getdate())-year(cssj) as '年龄','Year of Birth:' as 'Birth:',year(getdate())-sage as 'BirthDay',lower(sdept) 'department'
    from student

    选择表中的若干元组

    1.取消取值重复的行

    在SELECT子句中使用DISTINCT短语

    select /*(默认 ALL)*/ sno
    from sc
    
    select distinct sno,cgrade
    from sc

    注意DISTINCT短语的作用范围是所有目标列

    2.查询满足条件的元组

    WHERE子句常用查询条件
    查询条件 谓词
    比较 =、>、<、>=、<=、!=、<>、!>、!<、NOT+其他比较运算符
    确定范围 BETWEEN...AND...、NOT BETWEEN...AND...
    确定集合 IN、NOT IN
    字符匹配 LIKE、NOT LIKE
    空值 IS NULL、NOT IS NULL
    多重条件 AND、OR

    (1)比较大小

    (2)确定范围

    (3)确定集合

    例:查询系别为IS、MA、CS的学生信息

    select *
    from student
    where sdept IN('IS','MA','CS')

    (4)字符串匹配

    [NOT] LIKE ‘< 匹配串>’ [ESCAPE ‘<换码字符>’]

    <匹配串>:指定匹配模板

    匹配模板:固定字符串或含通配符的字符串

    当匹配模板为固定字符串时,

    可以用 = 运算符取代 LIKE 谓词,用 != 或 <> 运算符取代 NOT LIKE 谓词

    通配符

    % (百分号)代表任意长度(长度可以为0)的字符串

    例: a%b 表示以a开头,以b结尾的任意长度的字符串。如acb,addgb,ab等都满足该匹配串。

    _( 下横线)代表任意单个字符

    例: a_b表示以a开头,以b结尾的长度为3的任意字符串。如acb,afb等都满足该匹配串。

    ESCAPE短语:

    当用户要查询的字符串本身就含有 % 或 _ 时,要使用ESCAPE '<换码字符>' 短语对通配符进行转义。

    匹配模板为固定字符串

    例:查询学号为95001的学生的详细情况

    select *
    from student
    where sno like '95001'/*等价于where sno = '95001'*/

    匹配模板为含通配符的字符串

    例:查询名字中第2个字为‘阳’字的学生的详细信息

    select *
    from student
    where sname like '_阳%' 

    使用换码字符将通配符转义为普通字符

    例:查询以“DB_”开头,且倒数第三个字符为'i'的课程的详细情况

    select *
    from course
    where cname like 'DB\_%i__' 
    escape ''

    (5)涉及空表的查询

    使用谓词IS NULL或IS NOT NULL ( “IS NULL”不能用“= NULL”代替 )

    (6)多重条件查询

    用逻辑运算符AND和OR来联结多个查询条件 ( AND的优先级高于OR,但可以用括号改变优先级 )

    连接查询

    连接查询是同时涉及多个表的查询

    连接查询概念:

    同时涉及多个表的查询称为连接查询

    用来连接两个表的条件称为连接条件或连接谓词

    连接谓词中的列名称为连接字段

    注意:连接条件中的各字段类型必须是可比的,但字段名不必是相同的

    连接查询的执行过程

    首先在表1中找到第一个元组,然后从头开始扫描表2,逐一查找满足连接条件的元组,找到后就将表1中的第一个元组与该元组拼接起来,形成结果表中一个元组。

    表2全部查找完后,再找表1中第二个元组,然后再从头开始扫描表2,逐一查找满足连接条件的元组,找到后就将表1中的第二个元组与该元组拼接起来,形成结果表中一个元组。

    重复上述操作,直到表1中的全部元组都处理完毕。

    连接操作说明

    SQL的连接操作是通过关联表间的行的匹配而产生的结果。

    参与连接的表可以有多个,但连接操作在两个表之间进行,即两两连接。

    连接查询的主要内容

    SQL中连接查询的主要类型

    1.广义笛卡尔积

    不带连接谓词的连接,很少使用

    2.等值连接查询

    连接运算符为 ‘=’的连接操作注意事项:

    [<表名1>.]<列名1> = [<表名2>.]<列名2>

    任何子句中引用表1和表2中同名属性时,都必须加表名前缀。引用唯一属性名时可以加也可以省略表名前缀。

    3.非等值连接查询

     连接运算符不是‘=’的连接操作

    SQL连接的类型

    1.利用别名查询

    2.内连接查询

    3.外连接查询

    4.自身连接查询

    使用表别名进行查询

    USE stu
    select s.sno,s.sname,s.sdept
    from student as s

    内连接查询(INNER JOIN)

    内连接时,如果两个表的相关字段满足连接条件,就从这两个表中提取数据并组合成新的记录。只有满足条件的记录才能出现在结果集中。

    根据比较方式,内连接分为三种:

    1.等值连接

    使用=运算符比较被连接列的列值。

    2.非等值连接

    使用>、>=、<、<=、!>、!<和<>号进行比较运算的连接。

    3.自然连接

    等值连接的特殊情形,是去掉重复列的等值连接。

    内连接查询中的各个表地位平等,无主从关系。

    以下两种写法等同

    USE stu
    select s.sno,sname,sdept,cno,cgrade
    from student as s inner join sc on s.sno=sc.sno
    
    USE stu
    select s.sno,sname,sdept,cno,cgrade
    from student as s,sc
    where s.sno=sc.sno

    再加一个条件:cno要等于‘1’

    USE stu
    select s.sno,sname,sdept,cno,cgrade
    from student as s inner join sc on s.sno=sc.sno
    where sc.cno='1'
    
    USE stu
    select s.sno,sname,sdept,cno,cgrade
    from student as s,sc
    where s.sno=sc.sno and sc.cno='1'

    外连接查询

    外连接是只限制一张表中的数据必须满足连接条件,而另一张表中的数据可以不满足连接条件的连接方式。

    包括以下三种类型:

    1.左外连接(LEFT OUTER J0IN )

    2.右外连接( RIGHT OUTER J0IN)

    3.全外连接( FULL OUTER J0IN )

    外连接查询中的各个表地位不平等,有主从分别。

    (1)左连接

    是以“连接关键字”左边表为主表。输出结果以主表元组为基础,从表无对应信息则显示空值。

    是限制连接关键字右端的表中的数据必须满足连接条件,而不管左端表中的数据是否满足条件,均输出左端表中的内容

    例:

    USE stu
    select s.sno,sname,sdept,cno,cgrade
    from student as s left outer join sc on s.sno=sc.sno

    说明:该例子表明,不过学生有没有选课,都会输出到结果中

    (2)右连接

    以“连接关键字”右边表为主表。输出结果以“主表”元组为基础,“从表” 无对应信息则显示空值。

    与左外连接类似,是右端表中的所有记录都输出,限制左端表的数据必须满足连接条件。

    例:

    USE stu
    select s.sno,sname,sdept,cno,cgrade
    from student as s right outer join sc on s.sno=sc.sno

    说明:只有选课的学生,才会在结果中输出

    (3)完全连接

    不分主、从表。输出结果以“表”所有元组为基础,无对应信息则显示空值。

    全外连接查询的特点是左、右两端表中的记录都输出,如果没能找到匹配的元组,就使用NULL来代替。

    例:

    USE stu
    select s.sno,sname,sdept,cno,cgrade
    from student as s full outer join sc on s.sno=sc.sno

    说明:全外连接查询中所有表中的记录信息都保留在结果集中。

    (4)自身连接

    一个表与其自己进行连接,称为表的自身连接

    需要给表起别名以示区别

    由于所有属性名都是同名属性,因此必须使用别名前缀

    例:查询每一门课的间接先修课(即先修课的先修课)

    select first.cno,second.cpno
    from course as first,course as second
    where first.cpno=second.cno

    数据汇总查询

    主要内容:

    • 聚合函数
    • order by子句
    • group by子句
    • having 子句
    • compute子句
    • compute by 子句

    聚合函数

    主要聚合函数:

    计数:COUNT(*)或COUNT ( [DISTINCT|ALL] <列名> )

    计算总和:SUM ( [DISTINCT|ALL] <列名> )

    计算平均值:AVG ( [DISTINCT|ALL] <列名> )

    求最大值:MAX ( [DISTINCTHALL] <列名> )

    求最小值:MIN ( [DISTINCT|ALL] <列名> )

    DISTINCT短语:在计算时要取消指定列中的重复值

    ALL短语:不取消重复值(ALL为缺省值)

    注意:使用聚合函数时,select子句涉及显示的列名必须包含在聚合函数中

    查询学生总人数(包括空值)

    USE stu
    select count(*)
    from student

    查询选修了课程的学生人数(用DISTINCT来避免重复计算学生人数,不包括空值)

    USE stu
    select count(distinct sno)
    from sc

    查询信息工程系(IS)参加“数据库”课程考试的人数、最高成绩、最低成绩、平均成绩

    USE stu  
    select count(distinct sc.sno)as '考试人数',max(cgrade) as '最高分',min(cgrade) as '最低分',avg(cgrade) as '平均分'  
    from student inner join sc on student.sno=sc.sno inner join course on course.cno=sc.cno  
    where cname='数据库' and sdept='IS' 

    SQL查询结果的排序与分组

    SELECT语句除了可以检索数据以外,还可以在检索数据的过程中进行计算,甚至可以对检索的结果记录集进行排序、分组计算等操作,以达到更加复杂计算的目的。

    排序的关键字:ORDER BY

    分组的关键字:GROUP BY

    对查询结果排序

    (1)排序是指按照某个标准重新排列数据的顺序,以满足用户查看数据的顺序需求。

    (2)排序所使用的标准也叫排序“关键字”或“关键码”。参与排序的关键字可以是一列,也可以是多列。且多列参与排序时,列之间不必相邻。

    (3)按关键字值由小到大的顺序排列称为“升序 ( ASC)”,按关键字值由大到小的顺序排列称为“降序(DESC)”。对值相等且无法分出先后的数据按输入顺序排列。

    (4)排序主要针对查询的结果集实施,对数据表一般采用索引。

    使用ORDER BY子句(可以按一个或多个属性列排序,升序:ASC,降序:DESC,缺省值为ASC)

    当排序列含空值时:ASC时排序列为空值的元组最后显示,DESC时排序列为空值的元组最先显示

    例:查询全体学生情况,查询结果按所在系的系名升序排列,同一系中的学生按年龄降序排列。

    USE stu
    select *
    from student
    order by sdept ASC,sage DESC

    分组统计查询

    作用:按照某一(几)列的属性值分别进行查询或统计。

    注意:select子句涉及显示的列名必须包含在聚合函数或group by子句中。

    (1)单列分组

    例:根据课程分组,统计cgrade的总分与平均分

    USE stu
    select cname as '课程名',sum(cgrade) as '总分',avg(cgrade) as '平均分'
    from course inner join sc on course.cno=sc.cno
    group by cname

    (2)多列分组

    首先按照第一列分组,然后按照第二列分组.......

    USE stu
    select cname as '课程名',sdept as '系别',sum(cgrade) as '总分',avg(cgrade) as '平均分'
    from student inner join sc on student.sno=sc.sno inner join course on course.cno=sc.cno
    group by sdept,cname --注意是先按后面的排,先按cname排,再按sdept排

    (3)ALL关键字

    不符合where子句条件要求的记录对应字段返回空值

    GROUP BY ALL 列名

    (4)分组统计过滤查询(having子句)

    作用:按照having子句后标明的条件显示查询的结果。

    与where子句的区别: having 规定的为显示的条件,where 规定的是查询的条件。

    例: 根据课程分组,统计课程名称为“非数学”的cgrade字段的总分与平均分,显示平均成绩大于90分的查询信息。

    USE stu
    select cname as '课程名',sum(cgrade) as '总分',avg(cgrade) as '平均分'
    from student inner join sc on student.sno=sc.sno inner join course on course.cno=sc.cno
    where cname != '数学'
    group by cname
    having avg(cgrade)>=90

    例: 在成绩表中查询有两门以上课程在90分以上的学生的学号及课程数,新列名为“课程数”

    USE stu
    select sno,count(*) as '课程数'
    from sc
    where cgrade>=90
    group by sno
    having count(*)>=2

    小结:

    group by语句:分组

    order by语句:排序

    having语句:是一个过滤声明,是在查询返回结果集以对查询结果进行的过滤操作,在having中可以使用聚合函数

    where语句:是一个约束声明,使用where约束来自数据库的数据,where是在结果返回之起作用的,where中不能使用聚合函数

    明细汇总查询

    compute子句、但SqlServer2012不支持Compute语句(建议使用CUBE 和  ROLLUP)

    GROUP BY子句有个缺点,就是返回的结果集中只有合计数据,而没有原始的详细记录。

    如果想在SQL SERVER 中完成这项工作,可以使用COMPUTE BY子句。

    COMPUTE生成合计作为附加的汇总列出现在结果集的最后。当与BY一起使用时,COMPUTE 子句在结果集内生成控制中断和分类汇总。

    作用:明细与查询、统计结果同时显示

    例:查询数据库参加考试的人员信息并按系别分组分别统计最高成绩、最低成绩、平均成绩。

    USE stu
    select sc.sno,sc.cgrade,course.*,sdept
    from student inner join sc on student.sno=sc.sno inner join course on course.cno=sc.cno
    where cname='数据库'
    order by sdept
    compute max(cgrade),min(cgrade),avg(cgrade) by sdept

    子查询

    嵌套查询

    所谓嵌套查询,是指一个查询语句中完整地包含另一个查询语句。外层查询称为“父查询”,内层查询称为“子查询”。子查询还可以包含子查询,SQL支持由一系列的简单查询构成的多层嵌套查询。

    在SQL中,嵌套查询表现为一个查询语句完全被包含在另-个查询语句的WHERE或HAVING的条件短语中。

    从语法上讲,子查询就是一个用括号括起来的特殊“条件”,它完成的是关系运算,因此,子查询可以出现在允许表达式出现的地方。

    嵌套查询的执行过程是“由里到外”进行的,先执行最内层的子查询,依次由里到外执行各层的查询,即每个子查询在其上一级查询未处理之前已经完成计算,其结果用于建立父查询的查询条件。

    一个SELECT-FROM-WHERE语句称为一个查询块

    将一个查询块嵌套在另一个查询块的WHERE子句或HAVING短语的条件中的查询称为嵌套查询

    USE stu
    select sname --外层查询/父查询
    from student
    where sno=any
            (
                select sno --内层查询/子查询
                from sc
                where cno='2'
            )

    子查询的限制:不能使用order by子句,order by子句只能对最终结果排序

    层层嵌套方式反映了SQL语言的结构化

    有些嵌套查询可以用连接运算替代

    返回单值的子查询

    例:查询与‘李晨’在同一个系学习的学生。

    USE stu
    select *
    from student
    where sdept=
            (
                select sdept
                from student
                where sname='李晨'
            )

    例:将数据库课程的全体学生的成绩加上5分

    USE stu  
    update sc  
    set cgrade=cgrade+5  
    where cno=  
            (  
                select cno  
                from course  
                where cname='数据库'  
            )  

    返回多值的子查询

    (1) any谓词

    例:查询年龄小于“IS”系某一学生的非“IS”系学生的基本信息

    USE stu
    select *
    from student
    where sdept!='IS' and sage<any
                                (
                                    select sage
                                    from student
                                    where sdept='IS'
                                )

    例:查询学生年龄平均值不是最小的系

    USE stu
    select sdept
    from student
    group by sdept
    having avg(sage)>any
                        (
                            select avg(sage)
                            from student
                            group by sdept
                        )

    (2) all谓词

    例:查询小于“IS”系学生最小年龄的学生基本信息

    USE stu
    select *
    from student
    where sdept!='IS' and sage<all
                                (
                                    select sage
                                    from student
                                    where sdept='IS'
                                )
    
    USE stu
    select *
    from student
    where sage<
            (
                select min(sage)
                from student
                where sdept='IS'
            )

    (3) in谓词

    例:查询所有年龄小于20岁的学生的成绩

    USE stu
    select cgrade
    from  sc
    where sno in
                (
                    select sno
                    from student
                    where sage<20
                )

    例:查询IS系学生的选课情况

    USE stu
    select *
    from  sc
    where sno in
                (
                    select sno
                    from student
                    where sdept='IS'
                )

    例:查询没有选任何课程的学生的学号、姓名

    USE stu  
    select *   
    from student  
    where sno not in  
                   (  
                   select distinct sno  
                   from sc  
                    )  

    例:查询没有选修计算机课程的学生的学号、姓名。

    USE stu  
    select student.sno as '学号',sname as '姓名'  
    from student  
    where sno not in  
                    (  
                        select student.sno  
                        from student inner join sc on student.sno=sc.sno inner join course on course.cno=sc.cno  
                        where cname='计算机课程'  
                    )  

    (4) exists谓词(是否存在)

    带exists的子查询不返回任何数据,只产生真或者假。

    例:查询选修“数据库”课程的学生的姓名、学号、系别

    USE stu
    select s.sno,sname,sdept
    from  student as s
    where exists
                (
                    select *
                    from sc
                    where sc.sno = s.sno 
                        and sc.cno =
                                    (
                                        select cno
                                        from course
                                        where cname='数据库'
                                    )
                )
    -- 另一种写法
    USE stu
    select s.sno,sname,sdept
    from  student as s
    where exists
                (
                    select *
                    from sc inner join course on sc.cno=course.cno
                    where cname='数据库' and sc.sno=s.sno
                )
    -- 另一种写法
    USE stu
    select sno,sname,sdept
    from  student
    where sno in
                (
                    select sno
                    from sc
                    where cno in
                                (
                                    select cno
                                    from course
                                    where cname='数据库'
                                )
                )

    例:从课程表中删除在选课表中没有选课记录的课程记录

    USE stu
    delete
    from  course
    where not exists
                (
                    select *
                    from sc
                    where course.cno=sc.cno
                )

     几个高级查询运算词
    A: UNION 运算符
    UNION 运算符通过组合其他两个结果表(例如 TABLE1 和 TABLE2)并消去表中任何重复行而派生出一个结果表。当 ALL 随 UNION 一起使用时(即 UNION ALL),不消除重复行。两种情况下,派生表的每一行不是来自 TABLE1 就是来自 TABLE2。
    B: EXCEPT 运算符
    EXCEPT 运算符通过包括所有在 TABLE1 中但不在 TABLE2 中的行并消除所有重复行而派生出一个结果表。当 ALL 随 EXCEPT 一起使用时 (EXCEPT ALL),不消除重复行。
    C: INTERSECT 运算符
    INTERSECT 运算符通过只包括 TABLE1 和 TABLE2 中都有的行并消除所有重复行而派生出一个结果表。当 ALL 随 INTERSECT 一起使用时 (INTERSECT ALL),不消除重复行。
    注:使用运算词的几个查询结果行必须是一致的。

  • 相关阅读:
    HttpURLConnection请求网络数据的GET请求
    ImageLoader的Jar包加载图片
    使用HttpUtils 上传视频文件
    VideoView的视频播放
    VideoView的视频的全屏播放
    Android中在activity中弹出一个popwindow
    随心而记
    Java -- springboot 配置 freemarker
    Tensorflow替换静态图中的OP
    python 系统定时关机
  • 原文地址:https://www.cnblogs.com/jiamian/p/11875123.html
Copyright © 2020-2023  润新知