Oracle:同时从列中选择汇总:年初至今(年初至今),年初至今

时间:2020-01-16 23:10:36

标签: sql oracle select sum querying

我对Oracle来说还比较陌生,并且一天中的大部分时间都在尝试编写查询以在列上返回YTD和Fiscal YTD总数的查询。

仅具有相关列的表的简化版本类似于:

INVOICE_NUM  |  INVOICE_DATE  |  ORDER_CODE  |  ORDER_COST
    509         '14-FEB-20'      'ORD001'         34.99
    509         '14-FEB-20'      'ORD002'         14.99
    509         '14-FEB-20'      'ORD003'         59.99
    428         '16-JAN-20'      'ORD001'         34.99
    428         '16-JAN-20'      'ORD002'         14.99
    306         '14-DEC-19'      'ORD001'         34.99
    306         '14-DEC-19'      'ORD002'         14.99
    201         '15-NOV-19'      'ORD001'         34.99
    108         '16-OCT-19'      'ORD001'         34.99

“订单”是基于其他逻辑在每张发票中重复出现的经常性费用。我需要退货的是给定发票的总成本以及订购代码的年初至今总费用以及每个订购代码的财政年初至今(从11月1日开始)。对于此样本集,我的查询应返回发票509:

ORDER_CODE  |  CURRENT_INVOICE_TOTAL  |  YTD_TOTAL  |  FISCAL_YTD_TOTAL
 'ORD001'             34.99                69.69           139.96
 'ORD002'             14.99                29.98            44.97
 'ORD003'             59.99                59.99            59.99

截至目前,我所拥有的只是:

SELECT 
    order_code
    SUM(order_cost)
FROM 
    table_name
WHERE 
    invoice_num = :invoice_num
GROUP BY
    order_code

到目前为止,我在YTD上的尝试都失败了,但是开发环境中的数据也很差,因此没有真正的方法可以对其进行测试。到目前为止,我正计划用假数据创建一个临时表,以试图弄清楚这一点。

为清楚起见,请进行编辑:查询应返回给定发票日期的年初至今总数。例如,如果我要查询2020年的2018年5月的发票,则该发票应返回该发票中2018年1月至2018年5月的每个order_code的年初至今总额

3 个答案:

答案 0 :(得分:0)

您可以使用Conditional Aggregation,例如

SELECT order_code, 
       SUM(CASE WHEN invoice_num = :invoice_num then order_cost END ) AS current_invoice_total,
       SUM(CASE WHEN to_char(sysdate,'yyyy') = to_char(invoice_date,'yyyy') then
                  order_cost
              END ) AS ytd_total,
       SUM(CASE WHEN invoice_date 
             BETWEEN to_date(to_char(sysdate,'yyyy')-1||'-11-01','yyyy-mm-dd')
                 AND to_date(to_char(sysdate,'yyyy')||'-10-31'  ,'yyyy-mm-dd')
             THEN
                  order_cost
              END ) AS fiscal_ytd_total              
  FROM t
 GROUP BY order_code
 ORDER BY order_code

根据问题中的编辑,在表中使用Cross Join并从invoice_date绑定变量派生:invoice_num

SELECT t.order_code, 
       SUM(CASE WHEN invoice_num = :invoice_num THEN order_cost END ) 
             AS current_invoice_total,
       SUM(CASE WHEN invoice_date 
             BETWEEN TRUNC(invoice_date2,'yyyy')
                 AND invoice_date2
                THEN
                     order_cost
                END ) AS ytd_total,
       SUM(CASE WHEN invoice_date 
             BETWEEN to_date(to_char(invoice_date2,'yyyy')-1||'-11-01','yyyy-mm-dd')
                 AND invoice_date2
                THEN
                     order_cost
                END ) AS fiscal_ytd_total           
  FROM t
 CROSS JOIN ( SELECT MAX(invoice_date) AS invoice_date2 
                FROM t 
               WHERE invoice_num = :invoice_num ) t2
 GROUP BY order_code
 ORDER BY order_code

Demo

答案 1 :(得分:0)

您可以按以下方式使用conditional aggregation

Select order_code, 
       order_cost as CURRENT_INVOICE_TOTAL,
       Sum(case when invoice_date >= trunc(sysdate,'YEAR') then order_cost end) as YTD_TOTAL,
       Sum(case when invoice_date < add_months(trunc(sysdate,'YEAR'), 10) order_cost) as FISCAL_YTD_TOTAL
  From table_name
 Where invoice_num = :invoice_num
   And invoice_date >= add_months(trunc(sysdate,'YEAR'), -2)
   And invoice_date < add_months(trunc(sysdate,'YEAR'), 12)
Group by order_code, order_cost

此解决方案将使用invoice_date上的索引(如果有)。

干杯!

答案 2 :(得分:0)

您的会计年度从11月开始。这使聚合变得非常棘手,尤其是在10月 11月均可使用的版本。

但是,可以通过在日期上加上两个月并提取年份来计算会计年度。如果我们采用这种方法,那么一种方法是:

select order_code,
       max(order_cost) keep (dense_rank first order by invoice_date desc) as current_invoice_total,
       sum(case when trunc(invoice_date, 'YEAR') = trunc(sysdate, 'YEAR')
                then order_cost
           end) as YTD,
       sum(case when trunc(invoice_date + interval '2' month, 'YEAR') = trunc(sysdate + interval '2' month, 'YEAR') 
                then order_cost
           end) as Fiscal_YTD
from t
where trunc(invoice_date, 'YEAR') = trunc(sysdate, 'YEAR') or 
      trunc(invoice_date + interval '2' month, 'YEAR') = trunc(sysdate + interval '2' month, 'YEAR')
group by order_code;

Here是db <>小提琴。