2016-09-17 87 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'子句转换为内部连接。 –