多年的SQL会计期间

时间:2013-06-14 20:25:30

标签: sql oracle plsql crystal-reports

我正在为Oracle SQL Dev中的Crystal报表编写命令,但我遇到了一个问题。我的用户希望有参数允许他们以'yyyymm'格式使用起始年份/期间,并且结束参数相同。我遇到的问题是,使用这些参数他们还想从2012财年到2013年和10期(从2012财年)到06年(从2013财年)开始如何设置我的命令来处理这个问题?以下是我目前正在处理的一些代码表,视图,API等为了安全目的而更改了名称

SELECT SOO.PART_NO,
   AP.ACCOUNTING_YEAR,
   AP.ACCOUNTING_PERIOD,
   INVENTORY_PART_API.GET_DESCRIPTION(SOO.CONTRACT, SOO.PART_NO)         AS PART_DESCRIPTION,
   SUM(SO.QTY_COMPLETE)                                                           AS QTY_COMP,
   MAX(PART_COST_API.GET_TOTAL_ACCUM_COST(SOO.CONTRACT,SOO.PART_NO,'1','*','*'))  AS TOTAL_ACCUM_COST,       
   MAX(ORA_DATABASE_NAME)                                                         AS ORA_DATABASE_NAME
FROM SHOP_ORDER_OPERATION_TAB SOO
LEFT JOIN ACCOUNTING_PERIOD_TAB AP
   ON SOO.CONTRACT = '09'
   AND SOO.OPER_STATUS_CODE = '90'
   AND SOO.CONTRACT = AP.COMPANY
   AND SOO.LAST_ACTIVITY_DATE BETWEEN AP.DATE_FROM AND AP.DATE_UNTIL 
LEFT JOIN SHOP_ORD SO
   ON SOO.CONTRACT = '09'
   AND SOO.OPER_STATUS_CODE = '90'
   AND SO.ORDER_NO = SOO.ORDER_NO
   AND SO.RELEASE_NO = SOO.RELEASE_NO
   AND SO.SEQUENCE_NO = SOO.SEQUENCE_NO
   AND SO.CONTRACT = SOO.CONTRACT
WHERE SOO.CONTRACT = '09'
   AND SOO.OPER_STATUS_CODE = '90'
   AND NVL(AP.ACCOUNTING_PERIOD,0) BETWEEN SUBSTR('201205',5,2) AND SUBSTR('201306',5,2) 
   AND NVL(AP.ACCOUNTING_YEAR,0) BETWEEN 2012 AND 2013                
GROUP BY SOO.CONTRACT, 
   SOO.PART_NO ,
   AP.ACCOUNTING_YEAR,
   AP.ACCOUNTING_PERIOD
ORDER BY 
   AP.ACCOUNTING_PERIOD ASC,
   AP.ACCOUNTING_YEAR ASC,
  SOO.PART_NO ASC;

2 个答案:

答案 0 :(得分:0)

为什么不采用提供的YYYYMM并将它们转换为正确的日期,而不是按年份和月份进行划分,以便您可以使用BETWEEN,例如:

BETWEEN TO_DATE(yyyymm || '01', 'YYYYMMDD') AND LAST_DAY(TO_DATE(yyyymm || '01', 'YYYYMMDD'))

last_day会返回您所喂食的任何日期的月份的最后一天,因此在9月,4月,6月和11月没有30天的烦恼...

如果问题的关键是WHERE标准:

WHERE SOO.CONTRACT = '09'
   AND SOO.OPER_STATUS_CODE = '90'
   AND NVL(AP.ACCOUNTING_PERIOD,0) BETWEEN SUBSTR('201205',5,2) AND SUBSTR('201306',5,2) 
   AND NVL(AP.ACCOUNTING_YEAR,0) BETWEEN 2012 AND 2013   

考虑将上面的最后两行合并到:

AND TO_DATE(NVL(AP.ACCOUNTING_PERIOD,0) || NVL(AP.ACCOUNTING_YEAR,0) || '01', 'YYYYMMDD') 
    BETWEEN TO_DATE(yyyymm || '01', 'YYYYMMDD') AND TO_DATE(yyyymm || '01', 'YYYYMMDD')

必须仔细检查语法,但想法是将YYYYMM转换为正确的日期,以便您可以使用BETWEEN。

由于您没有比较实际日期,并且BETWEEN具有包容性,因此您根本不需要LAST_DAY功能。

答案 1 :(得分:0)

我做了一些与你的问题非常相似的事情。让生活变得如此简单的是将财政年度和时期结合在一起。

你在哪里

AND NVL(AP.ACCOUNTING_PERIOD,0) BETWEEN SUBSTR('201205',5,2) AND SUBSTR('201306',5,2) 
AND NVL(AP.ACCOUNTING_YEAR,0) BETWEEN 2012 AND 2013    

试试这个

AND NVL(AP.ACCOUNTING_YEAR,0) || NVL(AP.ACCOUNTING_PERIOD,0) BETWEEN '201205' AND '201306' 

我的会计年度和期间是VARCHAR,因此您输入的参数将起作用。如果您的FP是一个数字,您可能必须在参数中考虑该值。