2011-10-03 23 views
19

我碰到一個虛構的SQL來了,我不知道什麼是原來的打算,它看起來像:爲什麼表中有SELECT 1?

SELECT COUNT (*) 
INTO miss 
FROM billing b 
WHERE b.network= network1 
and NOT EXISTS (SELECT 1 from vas NV WHERE NV.network = 
b.network); 

爲什麼有選擇1,不存在?

回答

20

使用EXISTS關鍵字時,您需要有一個子選擇語句,並且只檢查一行的存在,該行的內容無關緊要。 SELECT是一個關鍵字,用於控制返回的內部的內容。 SELECT ing 1NV.network將返回相同數量的行。

因此,您可以選擇任何你想要的,以及規範的方式來做到這一點,包括SELECT NULLSELECT 1

請注意,您的查詢的替代方法是:

SELECT count(*) INTO miss 
    FROM billing b 
    LEFT JOIN vas NV ON NV.network = b.network 
WHERE b.network = network1 
    AND NV.network IS NULL 

(左連接填滿了NULL值右欄時ON條件無法匹配

+1

謝謝。你引用的替代查詢以某種方式導致了更高的基數:( –

+0

@Chin Boon:是'network1' null? – Benoit

+0

是的,我不認爲這個替代查詢實際上是相同的 – Magne

11
SELECT 1 from vas NV WHERE NV.network = b.network 

如果該查詢返回。一行,這意味着NV表中有一個記錄與結算表中的記錄匹配。

不存在否定它,sati如果NV表中沒有與結算表中的記錄相匹配的記錄,則在那裏填寫WHERE子句。

6

有關於使用一個極大AskTom Q & A存在VS在(或NOT EXISTS VS NOT IN):

http://asktom.oracle.com/pls/asktom/f?p=100:11:1371782877074057::::P11_QUESTION_ID:953229842074

基本上使用只存在檢查該行中是否存在子選擇,並不檢查每個匹配的行(哪個IN)。因此,在使用EXISTS或NOT EXISTS時,不需要實際選擇特定值,因此選擇一個佔位符(在本例中爲「1」)就足夠了。

在您的特定SQL語句中,NOT EXISTS子句可確保主SELECT只返回VAS表中沒有相應行的行。

2

這是你的代碼是主要從性能的立場來看

我只是提有關內部查詢寫入。因爲它需要用戶的解釋。什麼都SQL我已經使用應插入實際查詢用戶已在上文

and NOT EXISTS (SELECT 1 from vas NV WHERE NV.network = 
b.network); 

解釋內部查詢只 通常人們用它來把select NV.netword但是這回,這只是用來識別數據使用如果不存在數據。因此,理想情況下,在內部查詢中返回的內容甚至不在父查詢中檢查。因此,爲了減少解釋計劃中的字節數,我們使用select 1,這將具有最小的字節成本,並且反過來將減少查詢的成本。

要查看我建議您下載的Oracle SQL Developer和同時運行查詢的解釋計劃窗口,併爲每個查詢提防字節列的差異

SELECT nv.network from vas NV WHERE NV.network = b.network 
// cost will be depended on the value nv.network contain and that is selected in the where condition 

SELECT 1 from vas NV WHERE NV.network = b.network 
// cost will be independent of the column and cost lesser bytes selected and lesser cost. 

不存在,你將能夠檢查其他答案。

+2

在EXISTS中用1/0進行嘗試。應該仍然有效,因爲這是一個錯誤條件,所以沒有字節可以被返回:但是它並沒有在EXISTS中被實際評估,所以這個答案是錯誤的和誤導的 – gbn

+0

@gbn這個代碼示例是關於用戶初始查詢的這個問題我只提到內部查詢,因爲他的問題只是關於內部查詢。 –

相關問題