2013-05-01 30 views
1

下面是一個簡單的查詢:如何避免在SQL中鏈接WHERE .. IN語句?

SELECT customerName from customers 
WHERE customerNUMBER IN 
(SELECT customerNumber FROM orders 
    WHERE orderNumber 
    IN (SELECT orderNumber FROM orderdetails 
    INNER JOIN products on orderdetails.productCode = products.productCode 
    where products.buyPrice > 100)); 

我相信表是自我解釋。

有沒有更好的方法來做到這一點?

SQL noob here。

回答

13

我的建議是要改變這JOIN語法,而不是所有WHERE的/ IN子句過濾:

select c.customerName 
from customer c 
inner join orders o 
    on c.customerNumber = o.customerNumber 
inner join orderdetails od 
    on o.orderNumber = od.orderNumber 
inner join products p 
    on od.productCode = p.productCode 
where p.buyPrice > 100; 

如果需要,您可能必須在出現重複的情況下向查詢添加DISTINCT。

+2

什麼是你說的是JOIN魔術嗎? – Kermit 2013-05-01 16:36:52

+2

如果你採用這種方法,你會注意到兩件事。首先你會獲得巨大的性能提升。第二你的dba將停止擊中你。 – Zane 2013-05-01 16:39:32

+0

我會建議通過雖然...添加不同或分組這很好,可以返回重複的記錄。 – sgeddes 2013-05-01 16:40:39

8

使用正常的內部連接貫穿始終,一組由或不同的子句中折騰,如果你需要消除的DUP:

select customers.* 
from customers 
join orders on ... 
join orderdetails on ... 
join products on ... 
group by customers.customerNumber 
+1

+ 1代表「group by」 - 顯然是'customers。*'在一些RDBMS中僅由'customerNumber'進行分組時無法使用 – Aprillion 2013-05-01 16:34:28

2

EXISTS允許您合併所有子查詢部分。重複不是問題:

  • 只有customers表是從外部查詢可見
  • EXISTS產生每個customers行一個布爾結果:

-

SELECT customerName from customers cc 
WHERE EXISTS (
     SELECT * 
     FROM orders oo 
     JOIN orderdetails od ON od.orderNumber = oo.orderNumber 
     JOIN products pr ON od.productCode = pr.productCode 
     WHERE oo.customerNUMBER = cc.customerNumber 
     AND pr.buyPrice > 100 
     );