2012-09-12 101 views
1

這是那些日子之一,我只是無法弄清楚這一點。Where子句等於一個字段,不等於另一個

我有以下查詢:

SELECT * FROM wp_posts 
JOIN wp_term_relationships ON wp_term_relationships.object_id = wp_posts.ID 
WHERE term_taxonomy_id = 80 

顯然,這種選擇所有處於類別ID 80.我需要做的是選擇所有在80類,但不是什麼職位的職位在類別109

我已經試過這一點,但它只是選擇從類別80

SELECT * FROM wp_posts 
JOIN wp_term_relationships ON wp_term_relationships.object_id = wp_posts.ID 
WHERE term_taxonomy_id = 80 
AND term_taxonomy_id = 109 

這裏同樣職位的表結構:

wp_posts 

| ID | 
------------ 
| 1  | 
| 2  | 

wp_term_relationships 

| object_id | term_taxonomy_id | 
|-----------|------------------| 
|  1  |  80   | 
|  2  |  80   | 
|  1  |  109  | 

OBJECT_ID匹配POST_ID

查詢應該只因爲ID 1返回ID 2在這兩個80和109

我知道我這樣做了一百萬次,但我就是」爲了我的生活得到這個工作。任何幫助?

回答

1

這裏有一個辦法:

SELECT p.* 
    FROM wp_posts p 
    JOIN wp_term_relationships t 
    ON t.object_id = p.ID AND t.term_taxonomy_id = 80 
    LEFT 
    JOIN wp_term_relationships n 
    ON n.object_id = p.ID AND n.term_taxonomy_id = 109 
WHERE n.object_id IS NULL 

這將使用LEFT OUTER JOIN對長期關係表(別名爲n ),找到類別109中的匹配行,但隨後排除找到匹配項的任何行(通過中的條件條款,從那些不在類別109

在SQL說法wp_posts返回所以療法行,我們把這個操作,作爲「反連接」。

注意:如果(object_id,term_taxonomy_id)不唯一,例如,您在wp_term_relationships中有兩個(或多個)行(object_id = 2,term_taxonomy_id = 80),則此查詢確實有可能返回「重複」行。


一般來說,在MySQL中,我們發現JOIN操作(包括反連接操作)通常優於子查詢。

另一種選擇(這是很可能不執行,以及之前的查詢):

SELECT p.* 
    FROM wp_posts p 
WHERE EXISTS 
     (SELECT 1 
      FROM wp_term_relationships t 
      WHERE t.object_id = p.ID 
      AND t.term_taxonomy_id = 80 
     ) 
    AND NOT EXISTS 
     (SELECT 1 
      FROM wp_term_relationships n 
      WHERE n.object_id = p.ID 
      AND n.term_taxonomy_id = 109 
     ) 

注:這可能是MySQL生成此查詢(包括相同的執行計劃的加入和反連接操作)和前一個一樣。您需要在查詢上運行EXPLAIN以查看執行計劃,並測試其中一個是否比另一個「更快」。

還有其他的方法。性能將取決於可用的(合適的)索引,數據分佈和生成的執行計劃。

+0

+1,但回覆:「一般情況下,在MySQL中,我們發現,JOIN操作(包括反連接操作)通常優於子查詢「:對於某些類型的子查詢,這是正確的,但根據我的理解,最近版本的MySQL在識別IN(...)和NOT IN(...)作爲半連接和反連接時沒有任何問題(分別)並相應地優化。 – ruakh

+0

@ruakh ...這就是爲什麼我建議'EXPLAIN'輸出和測試是合適的。它絕對取決於哪個版本的MySQL。例如,在MySQL 5.1中,NOT IN(子查詢)不會產生與等價的「LEFT JOIN ... WHERE ... IS NOT NULL」查詢相同的計劃。 (有趣的是,'LEFT JOIN'查詢在解釋輸出中顯示''; not exists'',而一個'NOT EXISTS'查詢顯示了一個與'NOT IN'查詢相同的計劃,這兩個查詢都顯示了'DEPENDENT SUBQUERY'解釋輸出。 – spencer7593

0

您可以將其作爲聚合查詢來完成。我喜歡這種方法,因爲我覺得這是最靈活的定義一組中的元素:

select id 
from wp_posts p JOIN 
    wp_term_relationships t 
    ON t.object_id = p.ID 
group by id 
having sum(case when term_taxonomy_id = 80 then 1 else 0 end) > 0 and -- in 80 
     sum(case when term_taxonomy_id = 109 then 1 else 0 end) = 0  -- not in 109 
相關問題