ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

Oracle关于WINDOW SORT PUSHED RANK一些探究猜想

2022-06-21 09:00:47  阅读:178  来源: 互联网

标签:SORT sysdate ty create RANK char PUSHED time yyyy


 

Oracle关于WINDOW SORT PUSHED RANK一些探究猜想

 

最近遇到一条SQL,开发让我做出优化

with tmp as
 (select *
    from T_VERIFY_APPLY ty
   where ty.result_id in ('11', '12')
     and ty.sender_id = 'SWBHAP'
     and ty.create_time >= ADD_MONTHS(sysdate, -12)
     and ty.create_time <= sysdate),
tmp1 as
 (select count(*) as month_call_num
    from tmp
   where to_char(sysdate, 'yyyy/mm') = to_char(tmp.create_time, 'yyyy/mm')),
tmp2 as
 (select count(*) as last_year_month
    from tmp
   where to_char(ADD_MONTHS(sysdate, -12), 'yyyy/mm') =
         to_char(tmp.create_time, 'yyyy/mm')),
tmp3 as
 (select count(*) as month_on_month
    from tmp
   where to_char(ADD_MONTHS(sysdate, -1), 'yyyy/mm') =
         to_char(tmp.create_time, 'yyyy/mm')),
tmp4 as
 (select count(*) as this_year
    from tmp
   where to_char(sysdate, 'yyyy') = to_char(tmp.create_time, 'yyyy')),
tmp5 as
 (select count(*) as past_year_num
    from tmp
   where to_char(ADD_MONTHS(sysdate, -12), 'yyyy') =
         to_char(tmp.create_time, 'yyyy')),
temp as
 (select tl.entry_id,
         ty.create_time,
         ty.sender_id,
         row_number() over(partition by tl.entry_id order by 1) rn
    from t_verify_apply_list tl --418M
    left join T_VERIFY_APPLY ty --14M
      on ty.head_seq_no = tl.head_seq_no
   where ty.result_id in ('11', '12')
     and ty.sender_id = 'SWBHAP'
     and ty.create_time >= ADD_MONTHS(sysdate, -12)
     and ty.create_time <= sysdate),
tmp6 as
 (select count(temp.entry_id) month_goods_num
    from temp
   where temp.rn = 1
     and to_char(sysdate, 'yyyy/mm') = to_char(temp.create_time, 'yyyy/mm')),
tmp7 as
 (select count(temp.entry_id) month_goods_with
    from temp
   where temp.rn = 1
     and to_char(ADD_MONTHS(sysdate, -12), 'yyyy/mm') =
         to_char(temp.create_time, 'yyyy/mm')),
tmp8 as
 (select count(temp.entry_id) this_month_goods_with
    from temp
   where temp.rn = 1
     and to_char(ADD_MONTHS(sysdate, -1), 'yyyy') =
         to_char(temp.create_time, 'yyyy')),
tmp9 as
 (select count(temp.entry_id) this_year_goods_with
    from temp
   where temp.rn = 1
     and to_char(sysdate, 'yyyy') = to_char(temp.create_time, 'yyyy')),
tmp10 as
 (select count(temp.entry_id) year_goods_than
    from temp
   where temp.rn = 1
     and to_char(ADD_MONTHS(sysdate, -12), 'yyyy') =
         to_char(temp.create_time, 'yyyy'))
SELECT tmp1.month_call_num,
       tmp2.last_year_month,
       tmp3.month_on_month,
       tmp4.this_year,
       tmp5.past_year_num,
       tmp6.month_goods_num,
       tmp7.month_goods_with,
       tmp8.this_month_goods_with,
       tmp9.this_year_goods_with,
       tmp10.year_goods_than
  from tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10;
View Code

别看SQL很长,实际上“架构”很简单。我给优化成如下SQL了。

with tmp as
 (select count(case when to_char(ty.create_time, 'yyyy/mm') = to_char(sysdate, 'yyyy/mm') then 1 else null end) month_call_num,                        
         count(case when to_char(ty.create_time, 'yyyy/mm') = to_char(ADD_MONTHS(sysdate, -12), 'yyyy/mm') then 1 else null end) last_year_month,    
         count(case when to_char(ty.create_time, 'yyyy/mm') = to_char(ADD_MONTHS(sysdate, -1), 'yyyy/mm') then 1 else null end) month_on_month,        
         count(case when to_char(ty.create_time, 'yyyy') = to_char(sysdate, 'yyyy') then 1 else null end) this_year,                                
         count(case when to_char(ty.create_time, 'yyyy') = to_char(ADD_MONTHS(sysdate, -12), 'yyyy') then 1 else null end) past_year_num            
    from T_VERIFY_APPLY ty
   where ty.result_id in ('11', '12')
     and ty.sender_id = 'SWBHAP'
     and ty.create_time >= ADD_MONTHS(sysdate, -12)
     and ty.create_time <= sysdate),
temp as
 (select count(case when to_char(create_time, 'yyyy/mm') = to_char(sysdate, 'yyyy/mm') then 1 else null end) month_goods_num,                    
         count(case when to_char(create_time, 'yyyy/mm') = to_char(ADD_MONTHS(sysdate, -12), 'yyyy/mm') then 1 else null end) month_goods_with,    
         count(case when to_char(create_time, 'yyyy') = to_char(ADD_MONTHS(sysdate, -1), 'yyyy') then 1 else null end) this_month_goods_with,    
         count(case when to_char(create_time, 'yyyy') = to_char(sysdate, 'yyyy') then 1 else null end) this_year_goods_with,                    
         count(case when to_char(create_time, 'yyyy') = to_char(ADD_MONTHS(sysdate, -12), 'yyyy')  then 1 else null end) year_goods_than
    from ( select /*+ no_merge */ create_time from  (
    select ty.create_time,
                 row_number() over(partition by tl.entry_id order by 1) rn
            from t_verify_apply_list tl,T_VERIFY_APPLY ty
              where ty.head_seq_no = tl.head_seq_no
           and ty.result_id in ('11', '12')
             and ty.sender_id = 'SWBHAP'
             and ty.create_time >= ADD_MONTHS(sysdate, -12)
             and ty.create_time <= sysdate
             and tl.entry_id is not null
    )
   where rn = 1) )
SELECT tmp.month_call_num,
       tmp.last_year_month,
       tmp.month_on_month,
       tmp.this_year,
       tmp.past_year_num,
       temp.month_goods_num,
       temp.month_goods_with,
       temp.this_month_goods_with,
       temp.this_year_goods_with,
       temp.year_goods_than
  from tmp, temp;
View Code

两者等价,但是会引起wrong result的bug出来,这个后边在单独写一篇另说。

 

拿出原SQL中的部分,

select *
  from (select tl.entry_id,
               ty.create_time,
               ty.sender_id,
               row_number() over(partition by tl.entry_id order by ty.create_time) rn
          from t_verify_apply_list tl
          left join T_VERIFY_APPLY ty
            on ty.head_seq_no = tl.head_seq_no
         where ty.result_id in ('11', '12')
           and ty.sender_id = 'SWBHAP'
           and ty.create_time >= ADD_MONTHS(sysdate, -12)
           and ty.create_time <= sysdate)
 where rn = 1;

 

标签:SORT,sysdate,ty,create,RANK,char,PUSHED,time,yyyy
来源: https://www.cnblogs.com/PiscesCanon/p/16395574.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有