简体   繁体   English

Oracle:从列中选择总和作为两者:YTD(年初至今)、财政 YTD

[英]Oracle: Selecting Sums From Columns as both: YTD (Year to Date), Fiscal YTD

I'm relatively new to Oracle and have been spending the better part of the day trying to write a query to return YTD and Fiscal YTD totals on a column.我对 Oracle 比较陌生,并且一直在尝试编写查询以返回列上的 YTD 和 Fiscal YTD 总计。

A simplified version of the table with only relevant columns looks something like:只有相关列的表的简化版本看起来像:

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

Where an Order is a recurring charge that reappears in each invoice based on logic elsewhere.订单是根据其他地方的逻辑重新出现在每张发票中的经常性费用。 What I need to return is the total cost for a given invoice along with the YTD total for the order code as well as the Fiscal YTD (starting Nov 1st) for each order code.我需要返回的是给定发票的总成本以及订单代码的 YTD 总额以及每个订单代码的财政 YTD(从 11 月 1 日开始)。 For this sample set, my query should return for invoice 509:对于此示例集,我的查询应返回发票 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

As of now, all I have is:截至目前,我所拥有的是:

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

My attempts at YTD have failed thus far but the dev environment also has very poor data so there's no real way to test it.到目前为止,我在 YTD 的尝试都失败了,开发环境的数据也很差,所以没有真正的方法来测试它。 As of now, I'm planning to create a temp table with fake data to try to figure this out.到目前为止,我正计划创建一个带有假数据的临时表来尝试解决这个问题。

EDIT for clarity : The query should return the YTD totals for the given invoice date.为清楚起见编辑:查询应返回给定发票日期的 YTD 总数。 For example, were I to query, in 2020, an invoice from May 2018, it should return the YTD totals for each order_code contained within that invoice from Jan 2018 - May 2018例如,如果我在 2020 年查询 2018 年 5 月的发票,它应该返回 2018 年 1 月至 2018 年 5 月该发票中包含的每个 order_code 的 YTD 总计

You can use Conditional Aggregation such as您可以使用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

Depending on the Edit in the Question, Use a Cross Join Among your table and derived invoice_date from :invoice_num bind variable :根据问题中的编辑,在表中使用Cross Join并从:invoice_num绑定变量派生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 演示

You can use conditional aggregation as following:您可以使用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

This solution will use indexes on the invoice_date if there is any.此解决方案将使用invoice_date上的索引(如果有)。

Cheers!!干杯!!

Your fiscal year starts in November.您的财政年度从 11 月开始。 This makes the aggregation a big tricky, particularly a version that will work in both October and November.这使得聚合变得非常棘手,尤其是在 10 月11 月都可以使用的版本。

However, the fiscal year can be calculated by adding two months onto the date and extracting the year.但是,可以通过在日期上加上两个月并提取年份来计算会计年度。 If we take this approach, then one method is:如果我们采用这种方法,那么一种方法是:

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 is a db<>fiddle. 是一个 db<>fiddle。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM