数据库——SQL 中(数据查询)

版权声明:原创作品转载需标明作者与地址 https://blog.csdn.net/zjuwxx/article/details/90268606

数据查询在 SQL语句中占据很重要的地位,特写一篇专门博客

目录

一、单表查询

1.1选择表中的若干列

1.2选择表中的若干元组

1.3 ORDER BY子句

1.4聚集函数

1.5 GROUP BY子句

二、连接查询

2.1等值连接与自然连接

2.2自身连接

2.3外连接

三、嵌套查询

3.1概述

3.2带有 in谓词的子查询

3.3带有比较运算符的子查询

3.4带有EXISTS谓词的子查询

四、集合查询

交运算

并运算

差运算

五、基于派生表的查询

六、select语句的一般格式

6.1目标列表达式的可选格式

6.2聚集函数的一般格式

6.3 where子句的条件表达式的可选格式


select [all|distinct] <目标列表达式>[,<目标列表达式>] …
from <表名或视图名>[,<表名或视图名> ]…|(select 语句) 
    [as]<别名>
[ where <条件表达式> ]
[ group by <列名1> [ having <条件表达式> ] ]
[ order by <列名2> [ asc|desc ] ];
  • select 子句:指定要显示的属性列
  • from 子句:指定查询对象(基本表或视图)
  • where 子句:指定查询条件
  • group by 子句:对查询结果按指定列的值分组,该属性列值相等的元组为一个组。通常会在每组中作用聚集函数
  • having 短语:只有满足指定条件的组才予以输出
  • order by 子句:对查询结果表按指定列值的升序或降序排序 

一个SQL查询的含义

  1. 为 from子句中列出的关系产生笛卡尔积
  2. 在步骤1的结果上应用 where子句中指定的谓词
  3. 对于步骤2结果中的每个元组,输出 select子句中指定的属性或表达式的结果

一、单表查询

SQL查询的基本结构由三个子句构成:select, from, where。且必须以该次序写出

查询的输入是在 from子句中列出的关系,在这些关系上进行 where和 select子句中指定的运算,最终产生一个关系作为结果

1.1选择表中的若干列

1、查询指定列

/*
以大学数据库为例
*/

--找出所有教师所在的系名
select dept_name
from instructor;

2、查询全部列

  • SELECT关键字后面列出所有列名
  • <目标列表达式>指定为 *," * "表示“所有属性”
--instructor中的所有属性都被选中
select instructor.*
from instructor,teaches
where instructor.ID = teaches.ID;

--select *表示 from子句结果关系的所有属性都被选中,即 instructor,teaches的所有属性都被选中

3、查询经过计算的值

select子句<目标列表达式>可以是关系的属性,也可以是表达式,但不会导致对关系的任何改变

select salary-5000
from instructor;

4、使用列别名改变查询结果的列标题

select Sname aName, 'Year of Birth:' Birth,
    2014-Sage Birthday, lower(Sdept) Department
from Student;
--aName,Birth,Birthday,Department是别名

5、更名运算

  • from子句中的两个关系中可能存在同名属性,导致结果中出现重复的属性名
  • 如果我们在 select子句中使用算术表达式,结果属性就没有名字
  • 想改变结果中的属性名字

as子句既可以出现在 select子句中,也可以出现在 from子句中

--对于大学中所有讲授课程的教师,找出他们的姓名以及所讲述的所有课程标识
select T.name, S.course_id
from instructor as T, teaches as S
where T.ID = S.ID;

--使用 as语句重命名结果关系中的属性:old_name as new_name

1.2选择表中的若干元组

1、消除取值重复的行

SQL允许在关系以及SQL表达式结果中出现重复,如果想强行删除重复,可在 select后加入关键词 distinct,缺省为 all

select Sno
from sc;
--等价于
select all Sno
from sc;

--指定关键词 distinct后消除重复行
select distinct dept_name
from instructor;

2、查询满足条件的元组

常用查询条件

谓    词 

比    较

=, >, <, >=, <=, !=, <>, !>, !<;  not +上述比较运算符

确定范围

between … and …, not between … and …

确定集合

in <值表>,  not in <值表>

字符匹配

[not] like ‘<匹配串>’ [escape ‘<换码字符>’]

空    值

is null, is not null

多重条件(逻辑运算)

and, or, not

select name
from instructor
where dept_name='Comp.Sci' and salary>70000;

1.3 ORDER BY子句

可以按一个或多个属性列排序

升序:ASC;降序:DESC;缺省值为升序

例:查询选修了3号课程的学生的学号及其成绩,查询结果按分数降序排列

select Sno, Grade
from SC
where Cno='3' order by Grade DESC;

1.4聚集函数

  • 统计元组个数 count(*)
  • 统计一列中值的个数 count([distinct | all] <列名>)
  • 计算一列值的总和(此列必须为数值型)sum([distinct | all] <列名>)
  • 计算一列值的平均值(此列必须为数值型)avg([distinct | all] <列名>)
  • 求一列中的最大值和最小值 max([distinct | all] <列名>)min([distinct | all] <列名>)

sum和 avg的输入必须是数字集,其他运算符可作用在非数字数据类型的集合如字符串

 

1.5 GROUP BY子句

group by子句中给出的一个或多个属性用于构造分组,group by子句中的所有属性上取值相同的元组将被分在同一组

--找出每个系的平均工资
select dept_name, avg(salary) as avg_salary
from instructor
group by dept_name;

分组情况:     最终结果:

任何没有出现在 group by子句中的属性如果出现在 select子句中,只能出现在聚集函数内部,否则该查询错误

6、having短语与where子句的区别

作用对象不同

where 子句作用于基表或视图,从中选择满足条件的元组

having 短语作用于组,从中选择满足条件的组

 

 

二、连接查询

连接查询:同时涉及两个以上的表的查询

连接条件或连接谓词:用来连接两个表的条件。一般格式

  • [<表名1>.]<列名1>  <比较运算符>  [<表名2>.]<列名2>
  • [<表名1>.]<列名1> between [<表名2>.]<列名2> and [<表名2>.]<列名3>

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

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

2.1等值连接与自然连接

等值连接:关系R、S,取两者笛卡尔积中属性值相等的元组,例如 R.A=S.B,R.B=S.B

自然连接:是一种特殊的等值连接,运算作用于两个关系并产生一个关系作为结果,只考虑在两个关系模式中都出现的属性上取值相同的元组对,且把结果中重复属性去掉

  • 列出属性的顺序:先是两个关系模式中的共同属性,然后是只出现在第一个关系模式中的属性,最后是只出现在第二个关系模式中的属性
--from子句中可以用自然连接将多个关系结合在一起
select A1, A2, … ,An
from r1 natural join r2 natural join … natural join rm
where P;

 

2.2自身连接

自身连接:一个表与其自己进行连接

需要给表起别名以示区别

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

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

select first.Cno, second.Cpno
from Course first, Course second
where first.Cpno = second.Cno;

 

2.3外连接

外连接操作以指定表为连接主体,将主体表中不满足连接条件的元组一并输出

左外连接

  • 列出左边关系中所有的元组

右外连接

  • 列出右边关系中所有的元组

三、嵌套查询

3.1概述

一个 select-from-where语句称为一个查询块

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

select Sname  /*外层查询/父查询*/
from Student
where Sno in(
        select Sno  /*内层查询/子查询*/
        from SC
        where Cno= '2');
  • 上层的查询块称为外层查询父查询
  • 下层查询块称为内层查询子查询
  • SQL语言允许多层嵌套查询,即一个子查询中还可以嵌套其他子查询
  • 子查询的限制:不能使用ORDER BY子句

相关子查询:子查询的查询条件依赖于父查询

  1. 首先取外层查询中表的第一个元组,根据它与内层查询相关的属性值处理内层查询,若 where子句返回值为真,则取此元组放入结果表
  2. 然后再取外层表的下一个元组
  3. 重复这一过程,直至外层表全部检查完为止

3.2带有 in谓词的子查询

谓词 in测试元组是否是集合中的成员,集合由 select子句产生的一组值构成

--找出在2009年秋季和2010年春季学期同时开课的所有课程
select distincy course_id
from section
where semester = 'Fall' and year = 2009 and
    course_id in (select course_id
                  from section
                  where semester = 'Spring' and year = 2010);

in和 not in操作符能用于枚举集合

--找出"Mozart"和"Einstein"之外的老师
select distincy name
from instructor
where name not in ('Mozart','Einstein');

3.3带有比较运算符的子查询

当能确切知道内层查询返回单值时,可用比较运算符(><=>=<=!=< >

“至少比某一个大”用 > some表示

--找出至少比 Biology系某一个教师的工资高的所有老师的姓名
select distinct T.name
from instructor as T, instructor as S
where T.salary > S.salary and S.dept_name = 'Biology';
/* 注意这里 as语句的用法 */

select name
from instructor
where salary > some (select salary
                     from instructor
                     where depr_name = 'Biology');

“比所有的都大”用 > all表示

--找出比 Biology系所有教师的工资都高的所有老师的姓名
select name
from instructor
where salary > all (select salary
                    from instructor
                    where depr_name = 'Biology');

3.4带有EXISTS谓词的子查询

带有 exists谓词的子查询不返回任何数据,只产生逻辑真值“true”或逻辑假值“false”

  • 若内层查询结果非空,则外层的where子句返回真值
  • 若内层查询结果为空,则外层的where子句返回假值

由exists引出的子查询,其目标列表达式通常都用 * ,因为带exists的子查询只返回真值或假值,给出列名无实际意义

四、集合查询

intersect, union, except分别对应交、并、差运算,均可以自动去除重复,若想保留重复只需在后面加上 "all"

交运算

--找出2009年秋季和2010年春季同时开课的所有课程
(select course_id
from section
where semester = 'Fall' and year = 2009)
intersect
(select course_id
from section
where semester = 'Spring' and year = 2010);

--结果中出现的重复元组数等于在 c1和 c2中出现的重复次数里最少的那个

并运算

--找出2009年秋季开课,或2010年春季开课,或两个学期都开课的所有课程
(select course_id
from section
where semester = 'Fall' and year = 2009)
union
(select course_id
from section
where semester = 'Spring' and year = 2010);

--结果中出现的重复元组数等于在 c1和 c2中出现的重复元组数的和

差运算

--找出2009年秋季开课但不在2010年春季开课的所有课程
(select course_id
from section
where semester = 'Fall' and year = 2009)
except
(select course_id
from section
where semester = 'Spring' and year = 2010);
--except运算从其第一个输入中输出所有不出现在第二个输入中的元组

--结果中出现的重复元组数等于在 c1中出现的重复元组数减去 c2中出现的重复元组数(前提是结果为正)

五、基于派生表的查询

子查询不仅可以出现在 where子句中,还可以出现在 from子句中,这时子查询生成的临时派生表成为主查询的查询对象

如果子查询中没有聚集函数,派生表可以不指定属性列,子查询SELECT子句后面的列名为其缺省属性

--找出系平均工资超过50000美元的那些系中教师的平均工资
select dept_name,avg_salary
from (select dept_name,avg(salary)
      from instructor
      group by dept_name)
      as dept_avg (dept_name,avg_salary)
where avg_salary > 50000;
--子查询的结果关系被命名为 dept_name,其属性名是 dept_name和 avg_salary

六、select语句的一般格式

select [all|distinct] <目标列表达式>[,<目标列表达式>] …
from <表名或视图名>[,<表名或视图名> ]…|(select 语句) 
    [as]<别名>
[ where <条件表达式> ]
[ group by <列名1> [ having <条件表达式> ] ]
[ order by <列名2> [ asc|desc ] ];

6.1目标列表达式的可选格式

目标列表达式格式

  • *
  • <表名>.*
  • COUNT([DISTINCT|ALL] * )
  • [<表名>.]<属性列名表达式>[,<表名>.]<属性列名表达式>]…

<属性列名表达式>可以是由属性列、作用于属性列的聚集函数和常量的任意算术运算(+,-,*,/)组成的运算公式

6.2聚集函数的一般格式

6.3 where子句的条件表达式的可选格式

by   云烟成雨yycy

猜你喜欢

转载自blog.csdn.net/zjuwxx/article/details/90268606