Oracle:Not exists
2011-08-02 17:32 Tracy. 阅读(644) 评论(0) 收藏 举报I agree with using not exists.
Consider a case where you want to perform more logic than just "One not in the other".
Consider Item, Sale, and SaleDetail:
create table Item
(
ItemId number(6),
ItemDescription varchar(200),
UnitPrice number(18,6)
)
/
Create table sale
(
SaleId number(6),
TransactionDate date
)
/
create table SaleDetail
(
SaleId number(6),
ItemId number(6),
Quantity number(18)
)
insert into item
values (1,'Toyota Prius',18500.95)
/
insert into item
values (2,'Lock Washer', .004)
/
insert into sale
values (1000,'15-Jun-2008')
/
insert into sale
values (1001,'23-Aug-2008')
/
insert into sale
values (1002,'05-Jan-2009')
/
insert into sale
values (1003,'09-Jan-2009')
/
insert into sale
values (1004,'15-Feb-2009')
/
insert into SaleDetail
values (1000, 1, 1)
/
insert into SaleDetail
values (1001, 1, 2)
/
insert into SaleDetail
values (1002, 1, 2)
/
insert into SaleDetail
values (1003, 2, 1000)
/
insert into SaleDetail
values (1004, 2, 1900)
/
Now, I want to know which items from the item table have yet to be sold in 2009 in a quantity
greater than 100 (what have i not yet sold in bulk this year?).
Two alternatives using outer join logic (both nasty to read and comprehend):
select i.*
from item i
left outer join saleDetail sd
ON i.itemId = sd.ItemId
AND sd.quantity > 100
Left outer join sale s
ON sd.saleId = s.saleid
and trunc(s.transactionDate,'YYYY') = to_date('01-JAN-2009','DD-MON-YYYY')
WHERE sd.itemId is null
or
select i.*
from item i
left outer join
(select sd_i.*
from saleDetail sd_i
JOIN sale s
on s.saleid = sd_i.saleid
where trunc(s.transactionDate,'YYYY') = to_date('01-JAN-2009','DD-MON-YYYY')) sd
ON i.itemId = sd.ItemId
AND sd.quantity > 100
WHERE sd.itemId is null
Now again, using the not exists (much easier to read and much easier to test what HAS been sold in
bulk in 2009 by removing the inner to outer join on itemId):
select *
from item i
where not exists (select 'x'
from saleDetail sd
JOIN sale s
ON sd.saleId = s.saleId
where sd.itemId =i.itemId
and quantity > 100
and trunc(s.transactionDate,'YYYY') =
to_date('01-JAN-2009','DD-MON-YYYY')
)
Many developers would even try moving the where-like and conditions in the outer join syntax into
the body of the where clause, thinking that it was just misplaced initially. Once it's in the
where, you've created an inner join dataset and no inner join would have the "non-inner-join anti
join" condition.
本文来自博客园,作者:Tracy.,转载请注明原文链接:https://www.cnblogs.com/tracy/archive/2011/08/02/2125292.html
浙公网安备 33010602011771号