2013-10-17 77 views
2

可以說我有兩張桌子,購物車和cart_item。購物車可以有一個或多個cart_items。SQL如何查找僅包含特定購物車項目的購物車?

Cart_items從項目表中「模板化」。像item_name這樣的屬性對於多個cart_items將是相同的。我想創建一個查詢,返回包含名爲Apple的cart_items的所有購物車(所有購物車屬性,不僅是id)AND香蕉AND胡蘿蔔。

以下是我試過的一些例子。

Table cart 
cart_id_pk 
cart_desc 
cart_total 
etc... 

Table cart_item 
item_id 
item_name 
cart_id_fk 

我第一次嘗試:

SELECT * FROM cart_item ci 
LEFT JOIN cart c 
ON ci.cart_id_fk = c.cart_id 
WHERE ci.item_name = 'Apple' AND ci.item_name = 'Banana' AND ci.item_name = 'Carrot' 
GROUP BY c.cart_id_pk 

這是行不通的,因爲在選擇每行只包含一個cart_item。

我的第二次嘗試:

WHERE ci.item_name = 'Apple' OR ci.item_name = 'Banana' OR ci.item_name = 'Carrot' 

將無法​​工作或者是因爲它會返回一個包含所有這些cart_items的至少一個車。

修補子查詢現在..不知道如果我在正確的軌道上。

幫助讚賞。

回答

1

你需要有

WHERE c.cart_id_pk IN (
    SELECT ci.cart_id_fk 
    FROM cart_item ci 
    WHERE ci.item_name = "Apple") 
AND c.cart_id_pk IN (
    SELECT ci.cart_id_fk 
    FROM cart_item ci 
    WHERE ci.item_name = "Banana") 
AND c.cart_id_pk IN (
    SELECT ci.cart_id_fk 
    FROM cart_item ci 
    WHERE ci.item_name = "Carrot") 

WHERE聲明...

這應該工作。

+0

如果您需要多於或少於3行,我會寫一點動態SQL來通過傳入參數迭代where子句。 – u07ch

+0

這種方法效果很好。你的例子是關閉的,ci.cart_id_pk在IN被假設爲ci.cart_id_fk或c.cart_id_pk之前。 – payling

1

您可以使用COUNT(*)子句來計算一個子查詢相匹配的項目,具體如下:

SELECT * 
FROM cart c 
WHERE cart_id IN (SELECT cart_id_fk 
        FROM  cart_item 
        WHERE  item_name IN ('Apple', 'Banana', 'Carrot') 
        GROUP BY cart_id_fk 
        HAVING COUNT(*) = 3 /* number of matching items*/) 

注意:此方法假定同樣的車不能有多個蘋果。根據OP不確定這是否正常。

+0

不會有多個蘋果。我運行了這個查詢,但它沒有結束,幾分鐘後我中斷了執行。我運行了Amber的查詢,它在不到一秒內成功執行。計數函數是否會導致性能問題?我的購物車表中有大約20,000條記錄,物品表中有40,000條記錄。 – payling

+0

'HAVING'子句中的COUNT(*)'在性能方面可能不太合適。我想知道是否將它改爲'EXISTS'語義而不是'IN'會有所作爲。 – Mureinik