Re: Подсобите с запросом
От: Donz Россия http://donz-ru.livejournal.com
Дата: 03.08.09 22:31
Оценка:
Здравствуйте, 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 из внешнего запроса во внутреннем, но вроде должно работать.
Ну и надо учитывать, что этот запрос очень неоптимальный.
Первое, что приходит в голову по поводу оптимизации, это добавление избыточной колонки с консолидированной информацией о продуктах заказа. Если исключения по статусам касаются только категорий, то как раз подходит. Можно взять битовую строку, где одним битом обозначить наличие в заказе хотя бы одного товара с категорией, которая соответствует этому биту. Так в запросе надо будет немного пошаманить с битовыми операциями, и никаких вложенных селектов.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.