2012-06-23 35 views
3

我有一個叫做「survey_product」結構如下表:MySQL的獨家排選擇

id int(11) 
order_id int(11) 
product_id int(11) 
pq1 varchar(2) 
pq2 varchar(2) 
pq3 varchar(2) 

此表存儲產品通過系統訂購。

這裏是在表中的一些數據記錄:

(1, 2, 20, '1', '1', 'y') 
(2, 2, 21, '1', 'y', 'y') 
(3, 2, 22, '1', 'y', 'n') 
(4, 2, 23, '1', 'y', 'y') 
(5, 2, 24, '1', 'n', 'y') 
(6, 3, 20, '1', 'n', 'y') 
(7, 3, 24, '1', 'n', 'y') 
(8, 3, 25, '1', 'n', 'y') 
(9, 4, 20, '1', 'n', 'y') 
(10, 4, 21, '1', 'n', 'y') 
(11, 4, 23, '1', 'n', 'y') 
(12, 4, 24, '1', 'n', 'y') 

上面我們有3個訂單(ORDER_ID 2,3和4)。

我需要爲product_id = 21但沒有product_id = 20(訂單中的其他product_id無關緊要 - 我只對21和20感興趣)獲得order_id。

然後,我需要知道具有product_id 20和21的訂單(同樣,訂單中的其他產品無關緊要)。

這是基本的查詢,把所有的訂單特定產品現在:

SELECT order_id FROM survey_product 
WHERE product_id = 20 
AND (pq1 = '1' OR pq1 = '2' OR pq1 = '3') 

我如何能做到這一點任何想法?

我已經試過

SELECT order_id FROM survey_product 
WHERE product_id IN (20) AND product_id NOT IN (21) 
AND (pq1 = '1' OR pq1 = '2' OR pq1 = '3') 

但它不包括所有其它值。

非常感謝。

回答

4

它通常是有益使用的JOIN,而不是在這種情況下,嵌套查詢:

SELECT sp.order_id 
     FROM survey_product AS sp 
LEFT JOIN 
      (SELECT order_id FROM survey_product WHERE product_id = 20) AS sp_t 
     ON sp.order_id = sp_t.order_id 
    WHERE sp_t.order_id IS NULL 
     AND sp.product_id = 21 
     AND sp.pq1 IN ('1', '2', '3') 

的查詢來獲取其order_id兩個20和21 product_id是相似的:你只需要使用 INNER JOIN沒有任何支票sp_t.order_id 。或者只是保持原樣,但如果你懶惰,請將IS NULL替換爲IS NOT NULL,但我想這會運行得更慢。 )

這是一個SQL fiddle玩。

+0

謝謝!這似乎產生了正確的結果。但它排除了訂單(product_id 22,23,24和25)中的其他product_id嗎? – bruno

+0

@ raina77ow的確看起來好多了。你能指點我一些書籍或解讀有關高效SQL的技巧嗎?或者這只是通過經驗「可學習」? –

+2

@nadirs當然,經驗不會受到傷害,但有一些非常有幫助的書籍和資源。其中,我想推薦最[這個美好的網站](http://use-the-index-luke.com/)。 – raina77ow

3

我通常做這種通過使用WHERE條件嵌套查詢:

SELECT order_id 
FROM survey_product 
WHERE product_id = 21 
AND pq1 IN ('1', '2', '3') 
AND order_id NOT IN (
    SELECT order_id 
    FROM survey_product 
    WHERE product_id = 20) 

基本上你從那裏product_id = 20,然後從主查詢中排除這些行找到所有order_id S,即你從選擇order_id小號行,其中product_id = 21但不在order_id中的子查詢結果。

+0

嗨!感謝這個想法。但是,每次嘗試運行查詢時都會超時。我在那張桌子上有大約100K行,所以我想這會增加太多的開銷。 – bruno