1. 程式人生 > 其它 >AtCoder Beginner Contest 238 E - E - Range Sums(建圖)

AtCoder Beginner Contest 238 E - E - Range Sums(建圖)

子查詢(subquery),查詢其結果用來作為另一個查詢的引數。

 

單值的子查詢

一個子查詢如果產生一個單純的資料,該子查詢就如同一個常量,那麼就可以像使用常量一樣使用它。在實際應用中,我們經常要求子查詢只返回一個值,這樣就可以將一列值和單個子查詢返回值進行比較,這時,可以使用等於(=)、不等於(<>)、大於(>)、小於(<)、大於等於(>=)、小於等於(<=)等運算子。

SELECT * FROM user
where dept_id  = (select id from dept where dept_name = 'IT')

在子查詢中使用聚合函式

SELECT * FROM user
where salary  > (select avg(salary) from user)

比較判式的兩邊均採用聚合分析的子查詢

SELECT * FROM user
where (select avg(salary) from user as user2 where user2.dept_id = user.dept_id )  > (select avg(salary) from user)

在SELECT子句中使用子查詢

SELECT *,
(select count(1) from user where `user`.dept_id = dept.id) as user_count
FROM dept 

  

多行的子查詢

一個子查詢除了可以產生一個單一值外,也可以產生一個關係,該關係可以包含若干元組。SQL提供了若干對於關係的操作符,併產生一個布林型的結果,這些操作符主要用在子查詢的結果關係上,它主要包括:IN、EXISTS、SOME(ANY)、ALL、UNIQUE等。

採用IN子查詢實現集合交運算

當使用IN運算子來引入子查詢時,就是告訴DBMS執行子查詢集合成員測試,即把源表中的列值與子查詢的返回結果進行比較,如果列值包與返回結果集中的列資料值之一相匹配,那麼IN判別式求值為True,查詢結果就包含這行資料。

SELECT * FROM user
where id in (select id from user where dept_id = 1)

採用IN子查詢實現集合差運算

SELECT * FROM user
where id not in (select id from user where dept_id = 1)

EXISTS子查詢

在某些情況下,我們只需要子查詢返回一個True或者False,子查詢資料內容本身並不重要,這時,可使用EXISTS判式來定義子查詢。EXISTS判式用來測試集合是否為空,它總是與子查詢結合使用,而且只要子查詢中至少返回一個值,EXISTS判式的值就為True。如果子查詢的結果表中沒有值(表中沒有行滿足子查詢的WHERE子句的搜尋條件),那麼EXISTS判式的值為False。

SELECT * FROM user
where exists (select * from dept where id = user.dept_id)

SELECT * FROM user
where NOT exists (select * from dept where id = user.dept_id)

SOME/ALL子查詢

只要我們使用了SQL比較運算子(等於=、不等於<>、大於>、小於<、大於等於>=、小於等於<=)中的一個來比較兩個表示式的值,那麼運算子前後的表示式都必須為單一值。只有當子查詢返回值為單值時,才可使用子查詢作為比較判式的表示式之一。而數量詞SOME、ANY和ALL則允許使用比較運算子將單值與子查詢返回的值加以比較,這裡的子查詢返回的結果可以是多行的。

SELECT * FROM user
where salary  >= ALL (select avg(salary) from user)

UNIQUE子查詢

UNIQUE運算子用來測試集合是否存在重複元組。與EXISTS判式相似,它總是與子查詢結合使用,而且只要子查詢結果中沒有重複記錄,UNIQUE判式的值就為True;如果子查詢的結果表中有重複的記錄,那麼UNIQUE判式的值為False。

SELECT * FROM user
where UNIQUE (select dept_id from dept where id = user.dept_id)  ×

myslq沒有提供對UNIQUE判式的支援

可以在子查詢中採用聚合函式實現上述查詢

SELECT * FROM user
where  (select count(1) from dept where id = user.dept_id) = 1

  

相關子查詢

由前面介紹的一些子查詢我們不難發現,有些複雜的子查詢需要執行若干次,因為每次執行時,都需要來自子查詢外部的元組變數的值,也就是說,子查詢的執行要依賴於上一層查詢元組的當前值,我們將這種子查詢稱之為相關子查詢。前面介紹的EXISTS子查詢,基本上全部是相關子查詢。

在HAVING子句中使用相關子查詢

在SQL中,DBMS使用WHERE子句中的搜尋條件來過濾查詢結果表中不想要的行,使用HAVING子句中的搜尋條件刪除那些不想要的。

SELECT * FROM user
HAVING  salary  > (select avg(salary) from user)

  

巢狀子查詢

子查詢也可以出現在其他子查詢中。位於其他子查詢內的子查詢被稱為巢狀的子查詢

SELECT * FROM user
where salary  > (select avg(salary) from user where dept_id in (select id from user where dept_id = 1)  )

  

使用子查詢建立檢視

使用子查詢,根據已有的表或者檢視創建出新的檢視。

create view view_user_s as
SELECT * FROM user
where salary  > (select avg(salary) from user )

  

參考:SQL查詢的藝術-第10章 子查詢