簡體   English   中英

PL SQL多行分析

[英]PL SQL multiple rows analysis

我在Oracle中有兩個表INVOICES和HOLDS,我正在使用invoice_id進行連接。 並非所有發票都具有保留,但某些發票將具有多個保留事件。 我只想選擇一張發票並解碼release_status字段。 如果有多個保持事件,我需要分析它是否已釋放。 如果一行沒有下達代碼,則整個發票仍將保留。 表格示例:

Invoice_num     |Hold_Reason    |Release_Lookup_code  

10001           |Inv Hold       |Quick release  
10002           |Inv Hold       |Quick release  
10003           |Inv Hold       |(NULL)  
10004           |Inv Hold       |Quick release  
10004           |Inv Hold       |Quick release  
10004           |Amt Hold       |(NULL)  
10005           |Inv Hold       |Variance Corrected  
10005           |Inv Hold       |Quick release  
10006           |  (NULL)       |(NULL)  

我想顯示的結果:

Invoice num |Hold Reason    |Hold Status 

10001       |Inv Hold       |Released  
10002       |Inv Hold       |Released  
10003       |Inv Hold       |Held  
10004       |Inv Hold       |Held  
10005       |Inv Hold       |Released  
10006       |(NULL)         |Not Held 

目前,我只有這段代碼,它帶回多行:

select
inv.invoice_num,
hold.hold_reason,
(CASE WHEN hold.invoice_id is not null                                              
then (CASE WHEN HOLD.RELEASE_LOOKUP_CODE is null then 'HELD' else 'RELEASED' END)   
else 'NOT HELD' END) Hold_Status
from AP.AP_INVOICES_ALL INV,
AP.AP_HOLDS_ALL HOLD
WHERE inv.invoice_id = hold.invoice_id (+)
order by 1

我本來想計算發票數,但此后,我仍然需要分析Release_Lookup_Code字段的內容。 我不是在尋找完整的答案,只是關於如何進行的一些建議。

這樣的事情。 在發票保留表上進行重復。

   with AP_HOLDS_ALL(invoice_id, Hold_Reason, Release_Lookup_code) as
           (select 10001, 'Inv Hold', 'Quick release' from dual
            union all
            select 10002, 'Inv Hold', 'Quick release' from dual
            union all
            select 10003, 'Inv Hold', '' from dual
            union all
            select 10004, 'Inv Hold', 'Quick release' from dual
            union all
            select 10004, 'Inv Hold', 'Quick release' from dual
            union all
            select 10004, 'Amt Hold', '' from dual
            union all
            select 10005, 'Inv Hold', 'Variance Corrected' from dual
            union all
            select 10005, 'Inv Hold', 'Quick release' from dual
            union all
            select 10006, '', '' from dual)
       , AP_HOLDS_ALL_deplicated as
           (select s.*
                 , row_number()
                   over(partition by invoice_id
                        order by decode(Release_Lookup_code,  'Quick release', 1,  'Variance Corrected', 2,  3) desc)
                     rn
              from AP_HOLDS_ALL s)
       , AP_INVOICES_ALL(invoice_id) as
           (select 10001 from dual
            union all
            select 10002 from dual
            union all
            select 10003 from dual
            union all
            select 10004 from dual
            union all
            select 10005 from dual
            union all
            select 10006 from dual)
      select --inv.invoice_num,
             inv.invoice_id
           , hold.hold_reason
           , (case
                when hold.invoice_id is not null then
                  (case
                     when HOLD.RELEASE_LOOKUP_CODE is null then 'HELD'
                     else 'RELEASED'
                   end)
                else
                  'NOT HELD'
              end)
               Hold_Status
        from AP.AP_INVOICES_ALL INV, AP.AP_HOLDS_ALL_deplicated HOLD
       where inv.invoice_id = hold.invoice_id(+) and HOLD.rn = 1
    order by 1

keep ... dense_rank的答案類似的想法,但是使用keep ... dense_rank而不是顯式的步驟來查找行號:

-- CTEs to provide your sample data
with ap_invoices_all (invoice_id) as (
  select 10001 from dual
  union all select 10002 from dual
  union all select 10003 from dual
  union all select 10004 from dual
  union all select 10005 from dual
  union all select 10006 from dual
), 
ap_holds_all (invoice_id, hold_reason, release_lookup_code) as (
  select 10001, 'Inv Hold', , 'Quick release' from dual
  union all select 10002, 'Inv Hold', 'Quick release' from dual
  union all select 10003, 'Inv Hold', null from dual
  union all select 10004, 'Inv Hold', 'Quick release' from dual
  union all select 10004, 'Inv Hold', 'Quick release' from dual
  union all select 10004, 'Amt Hold', null from dual
  union all select 10005, 'Inv Hold', 'Variance Corrected' from dual
  union all select 10005, 'Inv Hold', 'Quick release' from dual
  union all select 10006, null, null from dual
)
-- end of CTEs for sample data
select
  inv.invoice_id,
  max(hold.hold_reason) keep (dense_rank last order by case
      when hold.release_lookup_code is null then 1 else 0
    end) as hold_reason,
  case
    when max(hold.hold_reason) is null then 'NOT HELD'
    when max(hold.release_lookup_code)
      keep (dense_rank last order by case
          when hold.release_lookup_code is null then 1 else 0
        end) is not null then 'RELEASED'
    else 'HELD'
  end as hold_status
from ap_invoices_all inv
left join ap_holds_all hold
on hold.invoice_id = inv.invoice_id
group by inv.invoice_id
order by 1;

得到:

INVOICE_ID HOLD_REA HOLD_STA
---------- -------- --------
     10001 Inv Hold RELEASED
     10002 Inv Hold RELEASED
     10003 Inv Hold HELD    
     10004 Amt Hold HELD    
     10005 Inv Hold RELEASED
     10006          NOT HELD

排名將優先考慮使用空發布代碼的保留記錄,以查找適當的保留原因並確定是否存在任何未決保留-確定是否保留或釋放。

在此版本中,如果您有兩個發票的未結保留,那么即使保留原因不同(例如,如果您同時擁有amt和inv都保留了10004),您也只會看到一次報告。 如果要同時查看這兩個字段,則可以按兩個字段進行分組,這將略微簡化其余查詢; 但是您也會看到由於兩種原因釋放的保全。 如果有首選項,您還可以優先考慮在該情況下看到的保留原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM