在您分享的代碼中存在問題和潛在的問題。
問題隱式轉換爲不帶格式字符串的日期。
在(BUSPLAN.START_DATE BETWEEN (:YEAR || '-04-01') AND (:YEAR+1 || '-03-31'))
兩個字符串正在形成,然後轉換爲日期。到日期的轉換將根據NLS_DATE_FORMAT的值而發生變化。確保字符串轉換正確to_date(:YEAR || '-04-01', 'YYYY-MM-DD')
。
潛在的問題,邊界在年底時間<>午夜。
Oracle的date
類型包含日期和時間。像這樣的測試將會遺漏在endDate午夜後發生的所有記錄。一個簡單的解決方案,排除someDate
上索引的使用是trunc(someDate) between startDate and endDate
。
更常用的方法是定義日期範圍和關閉的開放時間間隔。 lowerBound <= aDate < upperBound
其中lowerBound is the same as
startDate above and
upperBound is
endDate`加一天。
注:使用Oracle日期列,日期,總有一些應用商店午夜,如果你的應用程序之類的,那麼這是沒有問題的。檢查像check (trunc(dateColumn) = dateColumn)
這樣的約束將確保它保持這種狀態。
現在,回答實際提出的問題。
使用子查詢因子分解(Oracle的術語)/公用表表達式(SQL Server的術語)可以避免重複查詢。
代替計算出適當的年份,然後使用字符串彙總日期,下面的代碼從當前日曆年的午夜開始,即1月1日開始,trunc(sysdate, 'YEAR'))
。然後它在幾個月內增加一個抵消。當月份是1月,2月,3月,本財年在去年4月1日開始,即今年開始前的9個月開始。偏移量是-9。否則,本財年開始今年的4/1,今年開始加上三個月。
不是結束日期,而是計算上限,類似於下限,但偏移量大於下限的12,以在下一年獲得4/1。
with current_fiscal_year as (select add_months(trunc(sysdate, 'YEAR')
, case when extract(month from sysdate) <= 3 then -9 else 3 end) as LowerBound
, add_months(trunc(sysdate, 'YEAR')
, case when extract(month from sysdate) <= 3 then 3 else 15 end) as UpperBound
from dual)
select *
from busplan
cross join current_fiscal_year CFY
where (CFY.LowerBound <= busplan.start_date and busplan.start_date < CFY.UpperBound)
or (CFY.LowerBound <= busplan.end_date and busplan.end_date < CFY.UpperBound)
並且還更不請自來的建議。
我不得不處理財政年度的事情,避免查詢內重複的時間是低掛果。財務年度計算在許多查詢中保持一致和正確,這纔是工作的本質。所以我建議開發一個集中財務計算的開發PL/SQL包。它可能包括一個功能,如:
create or replace function GetFiscalYearStart(v_Date in date default sysdate)
return date
as begin
return add_months(trunc(v_Date, 'YEAR')
, case when extract(month from v_Date) <= 3 then -9 else 3 end);
end GetFiscalYearStart;
然後上面的查詢變爲:
select *
from busplan
where (GetFiscalYearStart() <= busplan.start_date
and busplan.start_date < add_months(GetFiscalYearStart(), 12))
or (GetFiscalYearStart() <= busplan.end_date
and busplan.end_date < add_months(GetFiscalYearStart(), 12))
這是很容易做到的CTE - 你需要一個例子 – Hogan
@Hogan是,請,我m不知道如何使用CTE – dave
您的邏輯似乎是如果當前年份是2015年,當前月份是「2015-04-01」到「2016-03-31」的會計年度的一月,二月,三月之一?如果當年是2015年,月份大於3月份,您希望'2016年4月1日到2017年3月31日'?或**下一個**會計年度。你在找什麼? –