2013-07-03 48 views
1

艱難的比賽我有一個包含從店鋪的訂單MySQL的:在同一臺

+----------------------------+ 
| orders_id | products_model | 
+----------------------------+ 
| 1000 | aa0000001  | 
| 1000 | bb0000002  | 
| 1000 | cc0000001  | 
| 1001 | aa0000001  | 
| 1002 | bb0000001  | 
| 1003 | cc0000001  | 
| 1004 | bb0000001  | 
| 1004 | aa0000001  | 
+----------------------------+ 

產品每一個訂單可以有,當然,一個或多個項目

我只需要訂單包含列表的表只有代碼以aa或bb開頭的商品(或兩者都有) 我不想列出包含以evey其他代碼類型開頭的代碼的商品的訂單。

實施例:

+-----------+ 
| orders_id | 
+-----------+ 
| 1001 |   
| 1002 | 
| 1004 | 
+-----------+ 

訂單1000必須被排除,因爲它有一個「抄送」項目「AA」的旁邊,「BB」的人 訂單1003必須被排除,因爲它有一個「抄送」項目

我開始嘗試比較匹配記錄的計數和每個訂單的所有記錄的計數.....但我很快就不得不停止......我是一個SQL新手,所以我迷失了自己在叢林中嵌套查詢:)

你能幫我嗎?

回答

3

認爲這可能是你需要什麼

SELECT DISTINCT orders_id FROM orders ord 
LEFT JOIN (SELECT DISTINCT Orders_Id 
    FROM orders 
    WHERE products_model LIKE 'cc%' OR products_model LIKE 'dd%') ccDdItems 
ON ccDdItems.Orders_id = ord.Orders_id 
WHERE ccDdItems.Orders_Id IS NULL 

由於LittleBobbyTables指出,如果你也有「EE」,「FF」等等,你可能要替換內部查詢NOT LIKE 'aa%' AND NOT LIKE 'bb%'

+0

儘管有效,並且OP沒有指定除「aa」,「bb」和「cc」以外的任何內容,但如果必須排除「ee」,「ff」等,這將開始陷入困境從列表中。 – LittleBobbyTables

+0

是的。更新了評論 –

2

你可以使用LEFT JOIN;

SELECT DISTINCT(o1.orders_id) orders_id 
FROM orders o1 
LEFT JOIN orders o2 
    ON o1.orders_id = o2.orders_id 
AND o2.products_model NOT LIKE 'aa%' 
AND o2.products_model NOT LIKE 'bb%' 
WHERE o2.orders_id IS NULL 

An SQLfiddle to test with

...或... NOT IN

SELECT DISTINCT(orders_id) orders_id 
FROM orders 
WHERE orders_id NOT IN 
    (SELECT orders_id FROM orders 
    WHERE products_model NOT LIKE 'aa%' 
     AND products_model NOT LIKE 'bb%') 

Another SQLfiddle

...或... NOT EXISTS

SELECT DISTINCT(orders_id) oid 
FROM orders 
WHERE NOT EXISTS 
    (SELECT 0 FROM orders o2 
    WHERE orders.orders_id = o2.orders_id 
     AND o2.products_model NOT LIKE 'aa%' 
     AND o2.products_model NOT LIKE 'bb%') 

Yet another SQLfiddle

0

有一個HAVING條款的方式,但它可能是爲自己好有點棘手:

的伎倆
SELECT 
    orders_id 
    FROM orders 
    GROUP BY orders_id 
    HAVING COUNT(NULLIF(products_model LIKE 'aa%' OR 
         products_model LIKE 'bb%', 
         TRUE)) = 0; 

部分是知道的行COUNT(<expression>)數量進行計數爲其<expression>返回非NULL結果。另一部分使用NULLIF(<test>, TRUE)來返回NULL,其中<test>TRUE

在這種情況下,我們有效地要求orders_id值的訂單有零條目,不符合products_model LIKE ...測試。

這裏的a SQLFiddle你可以使用它來玩耍。

這個版本比Joachim Isaksson提供的潛在回報是,沒有任何子查詢或連接,查詢計劃更簡單,因此性能可能會更好。然而,對於所有的性能參數,YMMV和你應該考慮現實的數據之前考慮它。任何性能增益可能不值得棘手的維護成本。