所謂的子查詢,,就是將一個select語句所得到的查詢結果再次用于select語句中,。實際工作中,,子查詢一般用于三種場合。 作為“表”使用任何一個select語句在用“()”進行分割之后,,都可以再次作為“表”來使用,。例如,上一篇文章《SQL語句多表數據查詢之第3篇:子集,、補集和差集》中的select語句采用的就是這種方法:
上述語句中用括號包起來的部分,,就是Access中用于生成多表并集數據的語句。簡單的說,,就是先左連,、再右連、最后再合并起來,。如果用的是SQLServer數據庫,,可以改用Full Join,,就會更加簡單。 這里用括號包起來的SQL語句所得到的查詢結果,,再次用于select時就相當于一個數據表了,,此時再做的任何查詢都是基于該查詢所作的二次查詢。作為“列字段”使用例如:
預覽效果如下圖,。 由于子查詢在作為“列字段”使用時,,只能返回一個字段的值。當需要進行一些復雜的數據處理時,,可以將子查詢同時作為“表”和“列字段”使用,。例如,我們要實現(xiàn)按總量排名的效果,,可以將以下子查詢同時用于“列字段”和“表”中:
為了更清晰的看到select語句結構,,我們將這個子查詢語句以SUB代替:
預覽效果如下圖。 如要按總量從低到高排序,,可以在第二個SUB語句的后面加上:order by sum(數量) desc,。 作為“查詢條件”使用將子查詢用于where中,是子查詢最常使用的方法,。 例如,,獲取訂單表中單價高于總體均價的數據記錄:
再如,要列出產品表中訂單數量大于等于兩條的數據記錄,,必須通過訂單中的子查詢來實現(xiàn),,這是因為產品表中僅記錄了產品名稱等信息,并沒有具體的訂單數據:
由此可見,,當把子查詢用作“查詢條件”時,其返回值也只能是一列的值,。當需要使用多列時,,可將其組合在一起返回,例如A列+B列+C列,,也可以在where中使用and或or連接多個條件,。 通過子查詢獲取多表之間的差集如下圖所示,交集中“客戶id”的值有C01,、C03和C04,,并集中還有C02、C05和C08,。只要將交集中的值排除掉,,剩下的不就是差集了嗎? 也就是:并集-交集=差集,。 按照常規(guī)的寫法,,select語句可以這樣:
可問題是,,這里的C01、C03和C04并不是固定的,,它們會隨著數據錄入的增加,、修改或刪除而發(fā)生變化。數據調整了,,兩個表得到的交集肯定也會調整,。因此,要想動態(tài)獲取條件判斷中的比較值,,最好的方法還是使用子查詢,。 例如,要獲取訂單表和客戶表中都存在的“客戶id”值的sql語句是:
由于該語句得到的是兩個表的交集,,因此,,在獲取“客戶id”時,指定其來源于A表或B表,,效果都是一樣的,。 假如將這個子查詢語句以subSQL表示,那么,,獲取差集的select語句完整寫法如下:
最終得到的查詢結果剛好就是上圖所標示的差集部分,。預覽效果如下圖。 這個select語句看起來雖然有點復雜,,但邏輯非常簡單,。 除了IN之外,使用EXISTS也能實現(xiàn)類似的效果,。它們的區(qū)別在于:IN中用到的select語句必須有具體的返回值,,而EXISTS不需要,因為EXISTS判斷的是是否存在指定的記錄,。如下圖,。 由于EXISTS用到的子查詢中同樣使用了訂單表和客戶表,為了避免和前面的并集語句相沖突,,這里的別名分別使用C和D來表示,。 如果覺得這個語句有點復雜,可以再看看下面這個簡單的例子: 這里的EXISTS同樣使用“客戶id”進行判斷,。由于客戶表中不存在內容為C08的記錄,,因而得到的查詢結果中會自動將該行剔除。 需要特別強調的是,,當使用EXISTS時,,子查詢中必須使用where語句將子查詢與主表或主查詢關聯(lián)起來,否則將無法起到任何效果。 |
|