2016-09-17 50 views
0

我有兩個表。當右表中有很多匹配行時左連接

Product(id, name) 
LineItem(id, product_id, order_id) 
Order(id, state) 

訂單可以有很多產品。一個產品可以同時屬於多個訂單。

我想選擇沒有特定狀態(即1,2)的訂單的產品。

我的查詢是

SELECT products.id, products.price 
    FROM "products" 
    LEFT OUTER JOIN line_items ON line_items.product_id = products.id 
    LEFT OUTER JOIN orders ON orders.id = line_items.order_id AND orders.status IN (1, 2) 
    WHERE (products.price > 0) AND (orders.id IS NULL) AND "products"."id" = $1 
    GROUP BY products.id, products.price [["id", 11]] 

11是一個產品,是不應該出現的結果的ID,但它確實。

+2

發佈您的查詢。將有助於指導您 –

+1

我刪除了無關的數據庫標記。請用您真正使用的數據庫標記問題。 –

+0

Jim我發佈了它。請查看 –

回答

2

I would like to select Products, which don't have orders with specific statuses(i.e. 1, 2).

SELECT * FROM products p -- I would like to select Products 
WHERE NOT EXISTS(   -- , which don't have 
    SELECT * 
    FROM orders o   -- orders 
    JOIN line_items li ON li.order_id = o.id 
    WHERE li.product_id = p.id 
    AND o.status IN (1,2) -- with specific statuses(i.e. 1, 2). 
    ); 
+1

最好的答案在我看來,並且很好的解釋了英語短語是如何翻譯成代碼的,我喜歡這個,當尋找不存在的時候,應該使用'NOT EXISTS'(或者NOT IN':選擇所有不在具有特定狀態的訂單集合中的產品。) –

1
select p.id, p.name 
from products p 
join lineitem l on l.product_id = p.id 
join `order` o on l.order_id = o.id 
group by p.id, p.name 
having sum(case when o.state in (1,2) then 1 else 0 end) = 0 
1

的想法是先從產品表並使用left join找到訂單,1或2,如果它們不存在,那麼你想要的產品:

select p.id, p.name 
from product p left join 
    lineitem li 
    on li.product_id = p.id left join 
    orders o -- a better name for the table 
    on li.order_id = o.id and 
     o.state in (1, 2) 
where o.id is null 
group by p.id, p.name; 
+0

您的想法很完美。但我不明白爲什麼這不起作用。我仍然沒有過濾所有記錄。請你可以查看你的SQL查詢?順便說一句:我投了你的答案。 –

+0

甚至更​​好,你可以查看我寫的關於主題描述的查詢。 –

+0

嗯,這應該選擇沒有狀態爲1或2的訂單的產品。至於您的查詢,您有'left join's,但它們通過'where'子句轉換爲內部連接。 –

相關問題