1. 程式人生 > >[瘋狂Java]SQL:子查詢

[瘋狂Java]SQL:子查詢

1. SQL標準對子查詢的定義:

    1) 簡單的講就是巢狀select查詢,SQL都支援多層巢狀查詢;

    2) 要求記憶體的查詢必須用括號()包起來;

    3) 子查詢可以出現的位置:

         i. from之後:查詢的實質就是一個臨時的檢視,因此可以將一個子查詢的結果當做一個表進行另外一個查詢;

!!既然是當成臨時檢視使用,最好是給該子查詢起一個別名,這樣方便在select後以及where中利用別名字首訪問臨時檢視的屬性列;

!!像這種子查詢也叫做行內檢視;

         ii. where之後:作為過濾條件的範圍(集合),由於子查詢的結果是一張檢視,而檢視中包含很多行,也就是說子查詢的結果就是返回了一些記錄的集合,而這個集合可以作為過濾的條件(範圍來使用),比如檢查當前記錄中的某個欄位的值是否落在子查詢得到的結果集合中,如果落在集合中就將該記錄篩選出來,否則就過濾掉;

2. 最典型的行內檢視的用法示例:

select t.col1, t.col2
from (select * from tableX) as t;

3. 作為過濾條件:

    1) 特殊情況:子查詢的結果剛好是一個單行單列的檢視,那麼檢視中那個唯一的值可以被當做一個標量處理,例如

select * from student_table
where id > (select count(*) from tableX);
!由於子查詢(select count(*) from tableX)得到的就是一個統計值(單行單列),因此可以當做一個標量來處理

    2) 搭配in檢查是否落在子查詢範圍內,例如:

select *
from student_table
where id in(select id from stuff_table);
!這裡子查詢的結果是一個標量集合,因此可以直接檢查id是否落在該集合中;

        ***考慮子查詢的結果是一個多值集合(向量集合,即子查詢結果的記錄有多列),那麼where的過濾物件必須也是多列的,例如:

select *
from student_table
where (id, name) in(select id, name from stuff_table);
!子查詢返回結果是向量(id, name)的集合,那麼where檢查的物件也必須是列數、型別對應相等的向量,SQL中可以直接用括號()構造元組,而元組就是向量了;

!!這個檢查的就是列的組合了,而不是單獨的每一列了!!

    3) 比較符+any/all:

         i. 一般一個值和一個集合具有以下幾種關係:

           a. 該值是否在這個集合中;

           b. 該值是否大於(小於等等)該集合中任意一個值;

           c. 該值是否比集合中任意一個值都(大、小、等於等於等等);

         ii. SQL中的語法為:

             a. value =any(集合)   // value是否落在集合中,相當於in

             b. value <>any(集合)   // value不在集合中,相當於not in

             c. value >any(集合)   // value大於集合中任意一個值即可,即大於集合中的最小值

             d. value < any(集合)   // value小於集合中任意一個值即可,即小於集合中的最大值

             e. value >all(集合)   // value大於集合中的所有值,即大於集合中的最大值

             f.  value <all(集合)   // value小於集合中的所有值,即小於集合中的最小值

         iii. 因此上述的集合就可以是子查詢,例如:

select * from t1
where val1 =any(select val1 from t2); // val1 in 子查詢
select * from t1
where val1 >all(select val2 from t2);  // t1中的val1要大於t2中val2的最大值
select * from t1
where (col1, col2) =any(select val1, val2 from t2);   // 向量的情形