2016-09-17 3 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 представляет собой идентификатор продукта, который не должен появляться в результате, но это делает.

+2

Отправьте запрос. Будет полезно вести вас –

+1

Я удалил посторонние теги базы данных. Пожалуйста, отметьте вопрос в базе данных, которую вы действительно используете. –

+0

Джим, я разместил его. Пожалуйста, просмотрите –

ответ

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

Лучший ответ на мой взгляд. И отличное объяснение того, как английская фраза переводится в код. Мне это нравится. При поиске небытия следует использовать 'НЕ СУЩЕСТВУЕТ'. (Или' НЕ 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', но они преобразуются во внутренние объединения с помощью предложения 'where'. –

 Смежные вопросы

  • Нет связанных вопросов^_^