Oracle 不要亂用between and

來源:互聯網
上載者:User

//需求:  
//查詢出使用者在沒有出差的時候錄入的資訊  
//分析:  
//子查詢:我們可以顯查詢出那些在出差時錄入資訊的使用者id,和時間  
//主查詢:我們從使用者明細表中檢索資訊,條件是,使用者id和write_date不在子查詢查到的id和時間  
//  
//使用者明細表  
with tmp_a as(  
     select 1 id,to_date('20100405','yyyymmdd') write_date,'tttttt1'  text from dual union all  
     select 1,to_date('20100406','yyyymmdd'),'tttttt2' from dual union all  
     select 1,to_date('20100407','yyyymmdd'),'tttttt3' from dual union all  
     select 1,to_date('20100408','yyyymmdd'),'tttttt4' from dual union all  
     select 1,to_date('20100409','yyyymmdd'),'tttttt5' from dual union all  
     select 1,to_date('20100410','yyyymmdd'),'tttttt6' from dual union all  
     select 1,to_date('20100411','yyyymmdd'),'tttttt7' from dual union all  
     select 1,to_date('20100412','yyyymmdd'),'tttttt8' from dual union all  
     select 1,to_date('20100413','yyyymmdd'),'tttttt9' from dual union all  
     select 1,to_date('20100414','yyyymmdd'),'tttttt10' from dual union all  
     select 2,to_date('20100405','yyyymmdd'),'ssssss1' from dual union all  
     select 2,to_date('20100406','yyyymmdd'),'ssssss2' from dual union all  
     select 2,to_date('20100407','yyyymmdd'),'ssssss3' from dual union all  
     select 2,to_date('20100408','yyyymmdd'),'ssssss4' from dual union all  
     select 2,to_date('20100409','yyyymmdd'),'ssssss5' from dual union all  
     select 2,to_date('20100410','yyyymmdd'),'ssssss6' from dual union all  
     select 2,to_date('20100411','yyyymmdd'),'ssssss7' from dual)  
//出差記錄表  
,tmp_b as(  
       select 1 id,to_date('20100407','yyyymmdd') begin_dt,to_date('20100409','yyyymmdd') end_dt from dual union all  
       select 1,to_date('20100411','yyyymmdd'),to_date('20100412','yyyymmdd') from dual union all  
       select 2,to_date('20100408','yyyymmdd'),to_date('20100410','yyyymmdd') from dual)  
//查詢 SQL  
//需要解決的問題  
//1. 同一使用者,間隔出差(存在不同的出差啟始時間) 不可簡單使用 not between  
//2. 有些使用者,可能沒有出差記錄                   不可簡單使用 a.id = b.id  
//通過過濾 (NOT IN) 查詢出不存在出差記錄的使用者明細  
select s.id,s.write_date,s.text  
from tmp_a s  
where (s.id,s.write_date) not in 
      (//存在出差記錄的使用者明細  
       select distinct a.id,a.write_date  
       from tmp_a a inner join tmp_b b   
            on a.id = b.id   
       where a.write_date   
             between b.begin_dt and b.end_dt  
       )  
        ID WRITE_DATE  TEXT  
---------- ----------- --------  
         1 2010-04-05  tttttt1  
         1 2010-04-06  tttttt2  
         1 2010-04-10  tttttt6  
         1 2010-04-13  tttttt9  
         1 2010-04-14  tttttt10  
         2 2010-04-05  ssssss1  
         2 2010-04-06  ssssss2  
         2 2010-04-07  ssssss3  
         2 2010-04-11  ssssss7 

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.