這是沒有回答,只是一種解釋
從對喬·斯特凡內利的回答您的評論我猜你不完全瞭解哪裏,並可在外部連接的問題。我們來看一個例子。
我們正在尋找所有供應商的最後訂單,即供應商沒有更新訂單的訂單記錄。
select *
from order
where not exists
(
select *
from order newer
where newer.supplier = order.supplier
and newer.orderdate > order.orderdate
);
這是直截了當的;該查詢與我們剛纔放入的單詞相匹配:查找不存在針對同一供應商的較新訂單的訂單。
與反連接模式同樣的查詢:
select order.*
from order
left join order newer on newer.supplier = order.supplier
and newer.orderdate > order.orderdate
where newer.id is null;
在這裏,我們加入他們所有的新訂單每一個訂單,因此很可能創造了巨大的中間結果。通過左外部連接,我們確保在供應商沒有更新的訂單時附上虛擬記錄。然後最後我們用WHERE子句掃描中間結果,只保留附加記錄的ID爲空的記錄。那麼,ID顯然是表的主鍵,並且不能爲空,所以我們在這裏保留的只是外連接的結果,其中較新的數據只是包含空值的虛擬記錄。因此,我們可以得到沒有新訂單的訂單。
談論一個巨大的中間結果:這怎麼能比第一個查詢更快?那麼,它不應該。第一個查詢應該實際上運行速度相同或更快。一個好的數據庫管理系統將會看到這一點,併爲兩個查詢制定相同的執行計劃。然而,一個相當年輕的DBMS可能會更快地執行反連接。這是因爲開發人員在連接技術方面付出了很多努力,因爲在每個查詢中都需要這些技術,並且還不關心IN和EXISTS。在這種情況下,可能會遇到NOT IN或NOT EXISTS的性能問題,並使用反連接模式。
現在是到WHERE/ON問題:
select order.*
from order
left join order newer on newer.orderdate > order.orderdate
where newer.supplier = order.supplier
and newer.id is null;
這看起來幾乎與以前一樣,但有些標準已就移動到哪裏。這意味着外連接得到不同的標準。以下是發生的情況:無論哪個供應商,每個訂單都可以找到所有新訂單‐!所以最後一個訂單日期的所有訂單都會獲得一個外連接虛擬記錄。但是,在WHERE子句中,我們刪除供應商不匹配的所有對。請注意,外連接記錄對於newer.supplier包含NULL,所以newer.supplier = order.supplier
對於它們來說從不是真的;他們被刪除。但是,如果我們刪除所有外連接的記錄,我們會得到與香草內連接完全相同的結果。當我們將外連接標準放在WHERE子句中時,我們將外連接轉換爲內連接。因此,查詢可重新寫爲
select order.*
from order
inner join order newer on newer.orderdate > order.orderdate
where newer.supplier = order.supplier
and newer.id is null;
而且在FROM和INNER JOIN不要緊的標準是否在ON或WHERE表;這是一個可讀性問題,因爲這兩個標準將同樣得到應用。
現在我們看到newer.id is null
永遠不會是真的。最終結果將爲空‐這正是您的查詢所發生的情況。
請編輯您的問題,並提供樣本數據和預期的結果。我得到的是查詢,但不是你真正想做的。 –
爲什麼你使用反連接技巧?使用「EXISTS」或「IN」進行直接查詢有問題嗎? –
當然。我也會和他們一起去。 – StrugglingCoder