Здравствуйте, Grog13, Вы писали:
G>Три таблицы:
G>orders { OrderID — PK, ... }
G>items { OID — FK }
G>states { OID — FK }
Не хватает как минимум еще одной таблицы, связывающей многие-ко-многим товары (items) и заказы (orders). Пусть будет orderitems( int order, int item )
G>Есть разные статусы заказов, которые хранятся в табличке states.
G>В табличке items — содержимое заказа.
G>Возникли трудности с запросом.
G>Нужно выбрать все заказы:
G>- у которых нет статусов { CLOSED, SENT }
G>- в содержании которых есть товары с определенной категорией (например category_id = 4) и для этих заказов нет статуса { PERIODIC }
Как-то так, наверное:
select o.* from orders o
inner join orderitems oi on oi.order = o.order
inner join items i on i.item = oi.item
where ( o.status <> CLOSED and o.status <> SENT ) or
( o.status <> PERIODIC and 4 not in
( select i2.category_id from items i2 inner join orderitems oi2 on oi2.item = i2.item inner join orders o2 on o2.order = oi2.order where o2.order = o.order ) )
Возможно, не совсем прав насчет использования o.order из внешнего запроса во внутреннем, но вроде должно работать.
Ну и надо учитывать, что этот запрос очень неоптимальный.
Первое, что приходит в голову по поводу оптимизации, это добавление избыточной колонки с консолидированной информацией о продуктах заказа. Если исключения по статусам касаются только категорий, то как раз подходит. Можно взять битовую строку, где одним битом обозначить наличие в заказе хотя бы одного товара с категорией, которая соответствует этому биту. Так в запросе надо будет немного пошаманить с битовыми операциями, и никаких вложенных селектов.