zoukankan      html  css  js  c++  java
  • Oracle:Not exists

    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.
    
  • 相关阅读:
    获取本周的周一日期与本周的周日日期
    用字符串连接SQL语句并用EXEC执行时,出现名称 '‘不是有效的标识符
    如何在iis中设置站点的编码格式。
    为应用程序池 'DefaultAppPool' 提供服务的进程意外终止-解决办法
    解决无法更改本地文件夹与 TFS 项目之间映射的问题
    远程过程调用失败0x800706be
    请求失败或服务未及时响应。有关详细信息,请参见事件日志或其他适用的错误日志
    HTML 基础篇
    python操作mysql数据库
    MySql的用法总结-2
  • 原文地址:https://www.cnblogs.com/tracy/p/2125292.html
Copyright © 2011-2022 走看看