3.8嵌套子查詢

1.       子查詢是嵌套在另一個查詢中的select-from-where表達式。

3.8.1用於判斷元素是否屬於集合

2.       子查詢可以出現在where子句中,與in 或者not in連用以判斷某個屬性值是否是一個集合的元素。

3.       可用下面的語句來查找09年秋天和10年春天都開設了的課程 :

4.       selectdistinct 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);

5.       雖然也可以用intersect來實現這個查詢,但上面的寫法無疑比較有新意。

6.       下面這種形式是允許的

7.       where (a,b,c) in (select a,b,c from t);

3.8.2與集合元素進行比較

8.       找出生物系不領最低工資的老師的查詢也可以寫成:

9.       select name
from instructor
where salary > some(select salary
from instructor
where dept name = ’Biology’);

10.   SQL還支持,< some, <= some, >= some, = some, and <> some其中=somein等價,而<>some則與not in 等價

11.   與some對應,還有< all, <=all, >=all, = all, and <> all

12.   <>all not in 等價,但是=all in不等價

13.   下面的查詢可用於查找平均工資最高的學院

14.   select dept name
from instructor
group by dept name
having avg (salary) >=all (select avg (salary)
   from instructor
   group by dept name);

3.8.4檢查關係是否爲空

15.   exists表達式求值:如果傳給它的子查詢的結果不爲空,返回true否則返回false

16.   外層查詢裏的表名可以用在嵌套查詢裏。我們稱使用了外層查詢中定義的關係別名的子查詢爲關聯子查詢correlated subquery

17.   在包含子查詢的查詢中要考慮關係別名的作用域的問題。在子查詢中只能使用在這個查詢以及包含這個子查詢的查詢中定義的關係別名。如果一個關係別名在子查詢和外層查詢中都定義了,使用子查詢中定義的別名。

18.   查找上了生物學院開的所有課程的學生的ID和名字:

19.   selectdistinct S.ID, S.name
from student as S
where not exists ((select course id
from course
where dept name = ’Biology’)
except
(select T.course id
from takes as T
where S.ID = T.ID))

3.8.4判斷集合中是否有重複值

20.   unique 只有一部分數據庫支持。如果傳給它的子查詢的結果爲空或者其中沒有重複值,返回true否則返回false

21.   當傳入的子查詢的結果中包含null值,則即使其它值都相等,但這兩個元組也不會被視爲相等。

3.8.5From子句中的子查詢

22.   因爲select-from-where表達式返回的是一個關係,因此在一個查詢中凡是要用到關係的地方都可以用select-from-where表達式。

23.   多數數據庫支持對from子句中的子查詢重命名——Oracle是個例外:

24.   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 > 42000;

25.   from子句中的子查詢不能使用在這個from子句中定義的其他的關係別名

26.   但是sql:2003支持Lateral子句,包含在這個子句中的子查詢中可使用子查詢所屬的from子句中已經出現過的關係中的屬性

27.   示例:查找每個老師的名字、工資、及該老師所在學院的平均工資:

28.   select name, salary, avg salary
from instructor I1, lateral(select avg(salary) as avg salary
                       from instructor I2
                       where I2.dept name= I1.dept name);

29.   支持lateral關鍵字的數據庫不多,書裏提到的只有DB2

3.8.6 With子句

30.   With子句用於定義只在包含With子句的語句中可見的臨時關係。

31.   with max budget (value) as
(select max(budget)
from department)
select budget
from department, max budget
where department.budget = max budget.value;

32.   大多數數據庫都支持With子句,少數不支持。

33.   使用with子句相較使用子查詢邏輯更清楚,可讀性更好,同時它還允許在一個查詢中多次使用某個視圖定義(With 子句構造的臨時關係可被視爲一個視圖)

34.   查找工資總和大於各個 學院 的工資總和 的平均值 的學院 :

35.   with dept total (dept name, value) as
(select dept name, sum(salary)
from instructor
group by dept name),
dept total avg(value) as
(select avg(value)
from dept total)
select dept name
from dept total, dept total avg
where dept total.value >= dept total avg.value;

3.8.7 Scalar 標量子查詢

36.   Scalar subquery :其結果只含一個元組,且該元組只有一個屬性。

37.   能使用只返回單個值的表達式的地方就能使用標量子查詢

38.   標量子查詢可出現在Select子句中:比如當我們要列出各個學院的名稱及這個學院的老師人數時:

39.   select dept name,
    (
select count(*)
    frominstructor
    wheredepartment.dept name =instructor.dept name)
    asnum instructors
from department;

40.    上面的查詢中用綠色標記出來的部分使用的是外部查詢中的關係名。像這樣在子查詢中使用外部查詢中的關係名的情況有點類似於編程寫嵌套循環的時候,裏面的循環可以使用外層循環中的變量。

41.   標量子查詢的結果仍然是一個關係,但是當標量子查詢用在需要單個值的地方時,SQL會從子查詢的結果關係中提取並返回那個值。

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