數據庫系統概念 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 子句中。


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