数据库系统概念 sql 查询语句 读书笔记

基本类型
sql标准支持多种固有类型,包括
char(n) : 固定长度的字符串,用户指定长度n,也可以使用全称character.
varcher(n): 可变长度的字符串,用户指定最大长度,等价于全称character varying
int: 整数类型(和机器相关的整数的有限子集),等价于全称integer
smallint: 小整数类型(和机器相关的整数类型的子集)
numeric(p,d): 定点数,精度由用户指定,这个数有p位数字(加上一个符号位),其中d位数字在小数点右边,所以在一个这种类型的字段上,numeric(3,1)可以精确储存44.5,但能精确储存444.5或0.32这样的数。
real,double,precision: 浮点数与双精度浮点数,精度与机器有关。
float(n): 精度至少为n位的浮点数。
 

通常说来,一个sql查询的含义可以理解如下:
1.为from子句中列出的关系产生笛卡儿积。
2.在步骤1的结果上应用where子句中指定的谓词。
3.对于步骤2结果中的每个元组,输出select子句中指定的属性(或表达式的结果)。


集合运算
并运算  --  union
如查询“找出在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 )
注意:union运算自动去除重复,如果保留重复,请使用 union all


交运算 --  intersect
如查询“找出在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 )
注意:如果要保留重复,请使用 intersect all


差运算 -- except
如查询“找出在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 )



空集
如果算术表达式的任一输入为空,则该算术表达式(涉及诸如+ , - , * ,或/)结果为空,例如如果一个查询中有一个表达式是r.A + 5,并且对于某个特定的元组,r.A 为空,那么对于此元组来说,该表达式的结果也为空。
sql将涉及空值的任何比较运算的结果视为unknown(既不是谓词is null, 也不是is not null),
and: true and unknown 的结果是 unknown, false and unknown 结果是 false, unknown and unknown 的结果是 unknown
or: true or unknown 的结果是 true, false or unknown 结果是unknown, unknown and unknown 的结果是 unknown
not: not unknown 的结果是 unknown
如:如果r.A为空,那么“1 < r.A ”和“not ( 1 < r.A )” 结果都是unknown
如果where子句谓词对一个元组计算出false或unknown,那么该元组不能被加入到结果集中。
可以使用is null/is not null测试空值。
可以使用is unknown/is not unknown测试一个表达式结果是否为unknown,而不是true或false。

当一个查询使用select distinct子句时,当比较两个元组对应的属性值时,如果这两个元组都是非空并且值相等,或者都空的,那么它们是相同的,如{ ('A',null), ('A',null) }被认为是相同的,distinct子句会保留相同元组的一份拷贝。这样的方式还应用于集合的并,交和差运算。
注意:上述对待空值的方式与谓词对待空值的方式不同,在谓词中“null = null”会返回unknown,而不是true。




聚集函数
聚集函数是以值的一个集合(集或多重集)为输入,返回单个值的函数。sql提供了五个固有的聚集函数。
平均值:avg
最小值:min
最大值:max
总和:sum
计数:count
注意:sql 不允许在用 count(*)时使用distinct




1.当sql查询使用分组时,一个很重要的事情是需要保证出现在select语句中的但没有被聚集的属性只能是出现在group by子句中的那些属性。换句话说,任何没有出现在group by子句中的属性如果出现在select子句中,它只能出现在聚集函数内部 ,否则这样的查询的错误的。例如,下述查询是错误的。因为ID没有出现在group by 子句中,但它出现在了select子句中,而且没有被聚集:
select dept_name,ID,avg(salary) from instructor group by dept_name;


2.having 子句中的谓语在形成分组后才起作用,因此可以使用聚集函数。 
    select dept_name,avg(salary) as avg_salary from instructor group by dept_name having avg(salary) > 4200 
  与select子句的情况类型,任何出现在having子句中,但没有被聚集的属性必须出现在gourp by子句中,否则查询 就被当成错误的。
  包括聚集,group by 或having 子句的查询含义可通过下述操作序列来定义:
  1.与不带聚集的查询情况类似,最先根据from子句来计算出一个关系。
  2.如果出现了where子句,where子句中的谓词将应用到from子句的结果关系中。
  3.如果出现了group by子句,满足where谓词元组通过group by 子句形成分组。如果没有group by 子句,满足where谓词的整个元组集将被当作一个分组。
  4.如果出现了having子句,它将应用到每一个分组上;不满足having子句谓词的分组将被抛弃。
  5.select子句利用剩下的分组产生查询结果中的元组,即在每个分组上应用聚集函数来得到单个元组。


  对空值聚集
除了count(*)外所有的聚集函数都忽略输入集合的空值。由于空值被忽略,有可能造成参加函数运算的输入值集合为空集。规定空集的count运算值为0,  其他所有聚集运算在输入为空集的情况下返回一个空值。


嵌套子查询
      where 后的子查询
1.在in后使用子查询
select distinct 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 )


2.用于集合比较
短语“至少比某一个大”在sql中用 >some ,如果要查询“找出所有的工资至少比Biolgy系某一个教师工资高的教师”,可用使用:
select name from instructor  where salary > some ( select salary from instructor where dept_name = 'Biolgy' )
(也可以使用自身连接:
select distinct T.name from instructor as T , instructor as S where T.salary > S.salary and S.dept_name = 'Biolgy')
sql允许<some, <=some , >= some , =some ,<>some ,注意 =some等价于in,但<>并不等价于not in 
类似于some,sql也允许<all, <= all,>all, >= all, = all, >all,<>all,注意 <>all等价于not in,但=all并不等价于in
如查询“找出平均工资最高的系”可以使用:
select dept_name from instructor gourp by dept_name having avg(salary) >= all ( select avg(salary) from instructor group by dept_name )


3.exists结构在作为参数的子查询非空时返回true
 如查询“找出在2009年秋季学期和2010年春季学期同时开课的所有课程”:
 select course_id from section as S where semester = 'Fall' and year 2009 and exists ( select * from section as T where semester = 'Spring' and year = 2010 and S.course_id =T.course_id );
如上所视,来自外层的一个相关名称(上述查询中的S)可以用在 where 子句的子查询中。使用了来自外层查询相关名称的子查询被称为相关子查询。


4.如果作为参数的子查询结果中没有重复的元组,unique结构(此结构尚未被广泛实现)将返回true值。
  如查询"找出所有在2009年最多开设一次的课程":
  select T.course_id from course as T where unique ( select R.course_id from section as R where T.course_id = R.course_id and R.year = 2009 )
  (也可使用下面等价表达方式:
    select T.course_id from course as T where 1 >= ( select count(R.course_id) from section as R where T.course_id = R.course_id and R.year = 2009 )) 


            from 子句中的子查询
如查询“找出所有系中工资总额最大的系”,在此having子句也是无能为力的,但可用from子句中的子查询轻易地写出:
select max(tot_salary) from ( select dept_name, sum(salary) where from instructor group by dept_name ) as dept_totol(dept_name,tot_salary)

with 子句
with子句提供了定义临时关系的方法,这个定义只对包含with子句的查询有效。如查询“找出具有最大预算值的系”:
with max_budget(value) as ( select max(budget) from department )   select budget from department ,max_budget where department.budget = max.budget.value.


      标量子查询
如果子查询只返回包含单个属性的单个元组,那它可以出现在 返回单个值的表达式能够出现的地方,这样的子查询称为子查询。
如查询“找出所有的系以及它们拥有的教师数”:
select dept_name, ( select count(*) from instructor where department.dept_name = instructor.dept_name  ) as num_instrucrots from department ;
标量子查询可以出现在select ,where 和having 子句中。


 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章