2013-02-16 50 views
3

我正在刷新我的SQL。
我正在閱讀有關子查詢以及使用相關子查詢引用外部的可能性。
例子:子查詢和外部引用相關子查詢的可能性

SELECT * 
FROM ORDERS O 
WHERE 'ROAD BIKE' = 
(SELECT DESCRIPTION FROM PART P WHERE P.PARTNUM = O.PARTNUM) 

這相當於一個連接:

SELECT O.ORDEREDON, O.NAME, 
O.PARTNUM, O.QUANTITY, O.REMARKS 
FROM ORDERS O, PART P 
WHERE P.PARTNUM = O.PARTNUM AND P.DESCRIPTION = 'ROAD BIKE' 

我的問題是,我沒有得到第一種形式,當/爲什麼我們使用它。何時外部引用的查詢有用?

+0

我想你可以說前者更清晰。 – 2013-02-16 21:05:33

+0

你也可以說前者要慢得多,直到SQL 6.0 – Achrome 2013-02-16 21:06:06

+0

@ExplosionPills:爲什麼它更清晰?我甚至都不知道這些查詢是如何工作的以及在哪裏應用它們。 – Cratylus 2013-02-16 21:06:53

回答

2

訂單有專門的部件號的引用,使Orders表的外鍵的部件編號。

我們希望所有的零件編號是「公路自行車」的訂單。

第一種形式首先做一個子查詢的每個記錄,以檢查是否O.PARTNUM是「公路自行車」零件號。

想它的方式是,主查詢正在經歷Orders表中的每個記錄。在每條記錄上,它執行一個子查詢,在查詢中使用PARTNUM字段。因此,如果您在子查詢中使用訂單記錄的PARTNUM,請選擇PARTNUM表中的PARTNUM記錄,然後選擇DESCRIPTION字段。然後,主要查詢的where子句檢查「Road Bike」是否等於從子查詢返回的描述。

我會建議不要使用第一種形式,因爲它是一個相關的查詢,你應該避免出於性能方面的相關查詢,因此使用第二種形式。第一種形式的更好的版本是:

SELECT * 
FROM ORDERS O 
WHERE O.PARTNUM = 
(SELECT P.PARTNUM FROM PART P WHERE DESCRIPTION = 'ROAD BIKE') 

這不是相關的查詢。數據庫可以執行一次子查詢,以「ROAD BIKE」爲描述獲取記錄的PARTNUM,然後使用條件WHERE O.PARTNUM等於子查詢的結果運行主查詢。

+0

是否有一個用例相關的子查詢是唯一的出路?解決一些具體問題? – Cratylus 2013-02-16 21:35:31

+0

這些是一些相關的子查詢,沒有其他等效的SQL而沒有相關的子查詢。那麼這是不可避免的。 – 2013-02-16 21:36:46

+0

我的意思是說,它不是SQL,每天都會寫出讓我們說。這是一個角落案例? – Cratylus 2013-02-16 21:37:45

2

總之,你應該避免像瘟疫這樣的相關子查詢。

相關子查詢對外部表中的每一行執行一次內部查詢。這將導致可怕的表現(1萬行的外部表將導致執行100萬次內部查詢!)

,另一方面聯接是非常有效和數據庫是在優化他們非常好。

如果可能,請始終將查詢表達爲優先於相關子查詢的連接。

+0

1)是否有一個使用案例,相關的子查詢是唯一的出路? 2)一般情況下,連接和相關子查詢或連接和子查詢之間的性能差異是什麼? – Cratylus 2013-02-16 21:34:57

+0

相關的子查詢將使MySQL 6.0復出。 – Achrome 2013-02-16 21:39:49

+0

@AshwinMukhija:不確定你的意思。我在MySQL中運行第一個表單(這是一個相關的子查詢),它的工作原理 – Cratylus 2013-02-16 21:57:59

0

這樣一個場景,一個子查詢可能是合適的是這樣的:

select some fields 
from some tables 
where some conditions are met 
and somefield = (select min(something) from etc) 

不過,我不知道這是相關子查詢。語義學不是我的強項。

+0

相關的子查詢是當你的子查詢引用你的外部查詢的一部分。在我的例子中注意'WHERE P.PARTNUM = O.PARTNUM'。表'O'被定義在*之外。 – Cratylus 2013-02-16 22:23:48