Помогите разобраться с объединением/пересечением/разностью.

Pavel Kilevatyh
Дата: 18.10.2005 17:35:16
Доброго дня.
Чесно не хотел создавать топик.

Если верить классикам, то SQL обеспечивает множественные операции реляционной алгебры, перечисленные в названии, операторами
UNION
INTERSECT
EXCEPT
.

UNION есть и работает.
Пересечение и разность можно смоделировать с помощью
WHERE ... IN (select_expr...) 
WHERE ... NOT IN (select_expr...) 

Но, вопервых, ограничение на кол-во элементов в IN, а вовторых низкая скорость работы. Если верить книжке "Мир Интербейз", IB/FB разворачивает IN в последовательность OR.

Подскажите рецептик, по которому можно получить разность двух запросов. И, если это не очевидно, пересечение.
Kull Damned
Дата: 18.10.2005 17:41:55
Сейчас тебя будут бить... Возможно даже ногами... Юзай JOIN и не парь моск!

Posted via ActualForum NNTP Server 1.3

Pavel Kilevatyh
Дата: 18.10.2005 17:58:28
Kull Damned
Сейчас тебя будут бить... Возможно даже ногами... Юзай JOIN и не парь моск!
Posted via ActualForum NNTP Server 1.3


Пардон, забыл добавить от себя - научите дурака.
Где-то я читал, возможно приснилось, что планировщик не очень хорошо обрабатывает джоины.
Но это было давно, когда я тока разбирался с IB и могу неправильно понять.
Подскажите как переписать
(select 
   A1,
   A2 
from 
   TableA
)
except
(select 
   B1 as A1,
   B2 as A2 
from 
   TableB
)

с помощью джоинов.
Уж проведите ликбез, не научился в институте (
Мимопроходящий
Дата: 18.10.2005 18:02:01

Привет, Pavel!
Ты пишешь:

Pavel
PK> Подскажите как переписать
(select A1, A2
from TableA)
except
(select B1 as A1, B2 as A2
from TableB)
Ты кого читаешь?
Срочно читать Грабера.

--
With best regards, Мимопроходящий.

Posted via ActualForum NNTP Server 1.3

Pavel Kilevatyh
Дата: 18.10.2005 18:10:25
Мимопроходящий

Ты кого читаешь?
Срочно читать Грабера.

--
With best regards, Мимопроходящий.

Posted via ActualForum NNTP Server 1.3


Читаю Гарсиа-Молина, Ульмана, Уидом "Системы баз данных". На Грабера денег не хватило.
Может со следующей зарплаты куплю.
Kull Damned
Дата: 18.10.2005 18:23:08
Где-то я читал, возможно приснилось, что планировщик не очень хорошо обрабатывает джоины.
А что он тогда правильно обрабатывает?
Уж проведите ликбез, не научился в институте (
Институт тебя не научит, тебя спасет только твоя голова...
SELECT T1.A1, T1.A2
  FROM T1
    LEFT JOIN T2 ON T2.A1=T1.A1 AND T2.A2=T1.A2
  WHERE T2.A1 IS NULL AND T2.A2 IS NULL

Posted via ActualForum NNTP Server 1.3

kdv
Дата: 18.10.2005 18:23:37
www.ibase.ru/devinfo/joins.htm
Pavel Kilevatyh
Дата: 18.10.2005 19:05:04
Kull Damned
Институт тебя не научит, тебя спасет только твоя голова...
SELECT T1.A1, T1.A2
  FROM T1
    LEFT JOIN T2 ON T2.A1=T1.A1 AND T2.A2=T1.A2
  WHERE T2.A1 IS NULL AND T2.A2 IS NULL

Posted via ActualForum NNTP Server 1.3


Вот за это спасибо.
Это как раз тот рецепт, которого мне не хватало.
Только почему-то эта конструкция не работает когда на месте T1 находится представление (версия сервера classic FB 1.0.3). Тогда в результат запроса попадает только одна строка.

Я наступил на общеизвестные грабли или что-то сделал не так?

kdv

www.ibase.ru/devinfo/joins.htm


Я не смог из этого текста вывести/вычитать фразу
WHERE T2.A1 IS NULL AND T2.A2 IS NULL
. Но все равно спасибо.
Kull Damned
Дата: 18.10.2005 19:20:07
Я наступил на общеизвестные грабли или что-то сделал не так?
Без более полной информации я смогу погадать только на кофейной гуще... :)

Posted via ActualForum NNTP Server 1.3

Pavel Kilevatyh
Дата: 18.10.2005 19:40:30
Kull Damned
Без более полной информации я смогу погадать только на кофейной гуще... :)
Posted via ActualForum NNTP Server 1.3


Есть два грида. В левом товар, подлежащий добавлению в правый. В правом - бланк заявки.
Товар не может присутствовать в заявке дважды, поэтому кроме ограничения UK, он не должен отображаться в левом гриде.

итого левый грид - разность множества ВЕСЬ ТОВАР и множества ТОВАР В БЛАНКЕ.

Фраза
select
    DETAIL_COMMODITY.DETAIL_COMMODITY_NO 
from
    DETAIL_COMMODITY LEFT JOIN REQUEST_ORDERS
on (
    DETAIL_COMMODITY.DETAIL_COMMODITY_NO = REQUEST_ORDERS.REQUEST_ORDERS_COMMODITY
)
where
REQUEST_ORDERS.REQUEST_ORDERS_COMMODITY is null

Работает и возвращает коды товаров, являющихся той самой разницей, а

select distinct
    DET_COMM_VIEW.DET_NO
from
    DET_COMM_VIEW LEFT JOIN COMM_BY_REQUEST_VIEW
on (
    DET_COMM_VIEW.DET_NO = COMM_BY_REQUEST_VIEW.NO_
)
where
COMM_BY_REQUEST_VIEW.NO_ is nul

где DET_COMM_VIEW вьюха, представляющая более полную инфу о товаре, выдает одну запись. Я специально выбираю только код товара, что б максимально приблизить условия к первому случаю.