暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 最后一家银行用来向供应商付款

ASKTOM 2020-07-13
349

问题描述

你好,

我对下面的查询不满意,因为它需要大约42秒才能运行并带来40000条记录。

select   
ss.sup_in , 
nvl(lb.lastbank,0)
from suppliers ss  
left join ( 
  select 
    bs.sup_tab, 
    bs.sup_pad, 
    bs.sup_in, 
    first_value(bk.bank_in) over (partition by bs.sup_in order by ps.pay_day desc) as lastbank 
  from  
  bills bs  
  inner join bills_payments bp  
  on  bs.bill_tab = bp.bill_tab  
  and bs.bill_pad = bp.bill_pad  
  and bs.bill_in  = bp.bill_in  
  and bs.org_tab  = bp.org_tab  
  and bs.org_pad  = bp.org_pad  
  and bs.org_in   = bp.org_in  
  inner join payments ps  
  on  bp.pay_tab = ps.pay_tab  
  and bp.pay_pad = ps.pay_pad  
  and bp.pay_in  = ps.pay_in  
  and bp.org_tab = ps.org_tab  
  and bp.org_pad = ps.org_pad  
  and bp.org_in  = ps.org_in  
  inner join banks bk  
  on  ps.bank_tab = bk.bank_tab  
  and ps.bank_pad = bk.bank_pad  
  and ps.bank_in  = bk.bank_in ) lb 
on  ss.sup_tab = lb.sup_tab  
and ss.sup_pad = lb.sup_pad  
and ss.sup_in  = lb.sup_in 

group by 
ss.sup_in , 
nvl(lb.lastbank,0)


还有其他方法可以做到这一点吗?我想让所有供应商用最后一家银行支付账单。如果没有付款,则显示0。

我注意到下面的子查询列出了每个供应商的所有付款,对我来说,这不是必需的:

 select 
    bs.sup_tab, 
    bs.sup_pad, 
    bs.sup_in, 
    first_value(bk.bank_in) over (partition by bs.sup_in order by ps.pay_day desc) as lastbank 
  from  
  bills bs  
  inner join bills_payments bp  
  on  bs.bill_tab = bp.bill_tab  
  and bs.bill_pad = bp.bill_pad  
  and bs.bill_in  = bp.bill_in  
  and bs.org_tab  = bp.org_tab  
  and bs.org_pad  = bp.org_pad  
  and bs.org_in   = bp.org_in  
  inner join payments ps  
  on  bp.pay_tab = ps.pay_tab  
  and bp.pay_pad = ps.pay_pad  
  and bp.pay_in  = ps.pay_in  
  and bp.org_tab = ps.org_tab  
  and bp.org_pad = ps.org_pad  
  and bp.org_in  = ps.org_in  
  inner join banks bk  
  on  ps.bank_tab = bk.bank_tab  
  and ps.bank_pad = bk.bank_pad  
  and ps.bank_in  = bk.bank_in


创建表和记录的命令在实时sql链接上可用。

致以最诚挚的问候,

西罗·斯塔尔施密特

专家解答

感谢您提供所有脚本。但是为了帮助慢速查询,我们还需要查看其他内容:

执行计划!

通过运行得到这个:

set serveroutput off
alter session set statistics_level = all;



select * 
from   table(dbms_xplan.display_cursor(null, null, 'ALLSTATS LAST'));


确保此计划包括E行、A行和缓冲区列。一旦你有了,就贴在这里。

I noticed that the subquery below lists all payments for each supplier and for me, it´s not necessary:

如果没有必要...那为什么会在查询中呢?!

外部查询使用lastbank,它来自banks表。看看加盟公司,这从供应商到银行都有。所以在我看来这是必要的。如果你不这么想,你需要解释原因。

可能是您可以通过左连接子查询中的所有表来使其更快。

并将last_value替换为:

max ( bk.bank_in ) keep ( dense_rank first order by ps.pay_day desc )


给出类似的东西:

select   
  ss.sup_in 
  ,nvl ( max ( bk.bank_in ) keep ( dense_rank first order by ps.pay_day desc ), 0 )
from suppliers ss  
left join bills bs  
on  ss.sup_tab = bs.sup_tab  
and ss.sup_pad = bs.sup_pad  
and ss.sup_in  = bs.sup_in 
left join bills_payments bp  
on  bs.bill_tab = bp.bill_tab  
and bs.bill_pad = bp.bill_pad  
and bs.bill_in  = bp.bill_in  
and bs.org_tab  = bp.org_tab  
and bs.org_pad  = bp.org_pad  
and bs.org_in   = bp.org_in  
left join payments ps  
on  bp.pay_tab = ps.pay_tab  
and bp.pay_pad = ps.pay_pad  
and bp.pay_in  = ps.pay_in  
and bp.org_tab = ps.org_tab  
and bp.org_pad = ps.org_pad  
and bp.org_in  = ps.org_in  
left join banks bk  
on  ps.bank_tab = bk.bank_tab  
and ps.bank_pad = bk.bank_pad  
and ps.bank_in  = bk.bank_in
group by  ss.sup_in ;


但实际上,我们需要执行计划,看看这里有什么选择。
文章转载自ASKTOM,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论