2013-11-22 102 views
0

我有一個web應用程序我試圖分析和優化,最後一件事之一是修復這個慢運行功能。我不是任何SQL專家,但是知道在一步SQL查詢中執行此操作的速度要比我現在執行的操作要快得多,包括多個查詢,排序和循環遍歷。SELECT語句跨2表

問題基本上是這樣的 - 我想從UserData對象表示的「用戶」表中的數據行,在給定一輪的「出價」表中沒有該用戶的條目。換句話說,我的數據庫中的哪些出價者尚未提交出價。

在SQL僞代碼,這將是

SELECT * FROM users WHERE users.role='BIDDER' AND 
users.user_id CANNOT BE FOUND IN bids.user_id WHERE ROUND=? 

(顯然,這不是有效的SQL,但我不知道SQL足夠好,把它連同正常)。

謝謝!

回答

2

你可以用LEFT JOIN來做到這一點。 LEFT JOIN就像INNER JOIN一樣在兩個表之間創建一個鏈接,但也會包含來自LEFT表(這裏的用戶)與右表沒有關聯的記錄。

這樣做,我們現在可以添加一個where子句來指定我們只需要與右表不關聯的記錄。

右表和左表取決於您編寫聯接的順序。左邊的表格是第一部分,右邊的表格(出價在這裏)在右邊。

SELECT * FROM users u 
LEFT JOIN bids b 
ON u.user_id = b.user_id 
WHERE u.role='BIDDER' AND 
b.bid_id IS NULL 
+0

唯一剩下的就是添加ROUND =? ON條款 – Fabian

+0

當然費邊!他的問題的這一部分並不清楚,所以爲了清晰起見,我將其刪除了! – Dave

+0

呵呵,是的,這個問題確實不是很清楚;)但是對於原來的海報:請把它放到ON子句中,它不會在WHERE子句中起作用 – Fabian

0

你可以做到這一點與左連接(與建議由Dave),或使用子查詢:

select * 
from users u 
where u.role = 'BIDDER' and not exists (
    select * 
    from bids b 
    where b.user_id = u.user_id and b.round = ?) 

或等價

select * 
from users u 
where u.role = 'BIDDER' and u.user_id not in (
    select b.user_id 
    from bids b 
    where b.round = ?) 

編輯

如果您想使用左連接和您要添加的查詢參數,你必須把它放在ON子句(沒有WHERE子句)中:

SELECT * FROM users u 
LEFT JOIN bids b 
ON u.user_id = b.user_id AND b.round = ? 
WHERE u.role='BIDDER' AND b.bid_id IS NULL 
0
SELECT * from users 
WHERE users.rol='BIDDER' 
AND users.user_id not in (SELECT user_id FROM bids WHERE round =?) 
0

性能比較的另一種選擇。鑑於你的僞代碼,你可能會發現它比左連接更具可讀性。

SELECT * 
FROM users u 
WHERE u.role='BIDDER' 
    AND NOT EXISTS (
    SELECT 1 
    FROM bids b 
    WHERE b.round = ? 
     AND b.user_id = u.user_id 
)