3.3 SQL查询的基本结构
SQL
查询的基本结构由三个子句构成:select
、from
和where
。
查询的输入是在from
子句中列出的关系,在这些关系上进行where
和select
子句中指定的运算,然后产生一个关系作为结果。
我们通过例子介绍SQL
的语法,后面再描述SQL
查询的通用结构。
3.3.1 单关系查询
instructor关系模式定义如下
instructor(ID,name,dept_name,salary)
找出所有教师的名字
我们考虑使用大学数据库例子
的一个简单查询:“找出所有教师的名字”。教师的名字可以在instructor
关系中找到,因此我们把instructor
关系放到from
子句中。教师的名字出现在name
属性中,因此我们把name
放到select
子句中。
1 | select name from instructor; |
其结果是由属性名为name
的单个属性构成的关系。
找出所有教师所在的系名
现在考虑另一个查询:”找出所有教师所在的系名”,此查询可写为:
1 | select dept_name from instructor; |
因为一个系有多个教师,所以在instructor
关系中,一个系的名称可以出现不止一次。
在关系模型的形式化数学定义中,关系是一个集合。因此,重复的元组不会出现在关系中。
在实践中,去除重复是相当费时的,所以SQL
允许在关系以及SQL
表达式结果中出现重复。因此,在上述SQL
查询中,每个系名在instructor
关系的元组中每出现一次,都会在查询结果中列出一次。
去除查询结果中的重复 select distinct
有时候我们想要强行删除重复,可在select
后加入distinct
关键词。如果我们想去除重复,可将上述查询重写为:
1 | select distinct dept_name from instructor; |
在上述查询的结果中,每个系名最多只出现一次。
保留查询结果中的重复 select all
SQL
允许我们使用关键词all
来显式指明不去除重复:
1 | select all dept_name from instructor; |
不过SQL
是默认保留重复元组的,所以all
关键词可以省略。
算术运算符
select
子句还可带含有加(+
)、减(-
)、乘(*
)、除(/
)运算符的算术表达式。
算术运算符可用于常数或者元组的属性
算术运算符的运算对象可以是常数
或元组的属性
。例如,查询语句:
1 | select ID, name, dept_name, salary*1.1 from instructor; |
将返回一个与instructor
一样的关系,只是属性salary
的值是原来的1.1
倍。这显示了如果我们给每位教师增长10%的工资的结果。注意这并不导致对instructor
关系的任何改变。
特定类型的算术函数
SQL
还提供了一些特殊数据类型,如各种形式的日期类型
,并允许一些作用于这些类型上的算术函数
。我们在4.5.1节进一步讨论这个问题。
where子句
where
子句允许我们只选出那些在from
子句的结果关系
中满足特定谓词的元组。
找出所有在Computer Science系并且工资超过70000美元的教师的姓名
考虑查询”找出所有在Computer Science系并且工资超过70000美元的教师的姓名”,该查询用SQL
可以写为:
1 | select name from instructor |
逻辑连词
SQL
允许在where
子句中使用逻辑连词and
、or
和not
。
逻辑连词的运算对象是包含比较运算符的表达式
逻辑连词`运算对象可以是包含比较运算符<
、<=
、>
、>=
、=
和<>
的表达式。SQL
允许我们使用比较运算符来比较字符串、算术表达式以及特殊类型,如日期类型。
在本章的后面,我们将研究where
子句谓词的其他特征。
大学数据库模式
classroom(building,room_number,capacity)
department(dept_name,building,budget)
course(course_id,title,dept_name,credits)
instructor(ID,name,dept_name,salary)
section(course_id,sec_id,semester,year,building,room_number,time_slot_id)
teaches(ID,course_id,sec_id,semester,year)
student(ID,name,dept_name,tot_cred)
takes(ID,course_id,sec_id,semester,year,grade)
advisor(s_ID,i_ID)
time_slot(time_slot_id,day,start_time,end_time)
prereq(course_id,prereq_id)