2014-01-20 56 views
4
+-------+-----------+------+----------------------+----------------------+ 
|RATE_ID|DESCRIPTION|CHARGE|FROM_DATE    |TO_DATE    | 
+-------+-----------+------+----------------------+----------------------+ 
|1  |small  |100 |01/01/2014 12:00:00 AM|31/03/2014 12:00:00 AM| 
+-------+-----------+------+----------------------+----------------------+ 
|2  |mediam  |200 |01/04/2014 12:00:00 AM|04/04/2014 12:00:00 AM| 
+-------+-----------+------+----------------------+----------------------+ 
|3  |big  |300 |05/04/2014 12:00:00 AM|31/12/2014 12:00:00 AM| 
+-------+-----------+------+----------------------+----------------------+ 

中存在讓的日期範圍內費用的樣品臺以上,我會像
start_date = to_date('30/mar/2014','dd/mon/yyyy')
end_date = to_date('05/apr/2014','dd/mon/yyyy')的輸入。發現號的日期範圍

所以輸入日期包含在兩天的收費100(rate_id = 1), 4天的收費200和1天的收費300以及合計1300

是否有任何簡單的方法來找到給定範圍內存在的天數,以便我可以計算total_charge。因爲目前我正在使用PL/SQL來使用loop來查找存在。

作爲一個整體: 從輸入,

30 and 31st march belongs to small(100 charge) => 100* 2 = 200 
1, 2, 3, 4 of april belongs to medium(200 charge) => 200*4 = 800 
5th april belongs to big (300 charge) => 300*1 = 300 
so 
the total:= 200 + 800 + 300 = 1300 

預先感謝。

+0

嘗試建立在函數的oracle turncate()http://www.oracle-base.com/articles/misc/oracle-dates-timestamps-and-intervals.php – zee

+0

對不起,但我不明白你的計算。對於3月3日的開始日期,將會有28天,這應該按照rate_id = 1來收取,這使得2800.不是嗎? – Incognito

+0

對不起,我修正了計算。請再看一遍 – ajmalmhd04

回答

0

您可以使用CONNECT BY生成結束之間的天名單,並開始約會,並與速率列表中加入此名單:

with v_days as (
    SELECT TRUNC (to_date('2014-04-05', 'YYYY-MM-DD') - ROWNUM + 1) dt 
    FROM DUAL 
    CONNECT BY ROWNUM <= (to_date('2014-04-05', 'YYYY-MM-DD') + 1 - 
     to_date('2014-03-30', 'YYYY-MM-DD')) 
), 
v_rates as (
    select 1 rate_id, 'small' rate, 100 charge, 
    to_date('2014-01-01', 'YYYY-MM-DD') start_date, 
    to_date('2014-03-31', 'YYYY-MM-DD') end_date 
    from dual union all 
    select 2 rate_id, 'medium' rate, 200 charge, 
    to_date('2014-04-01', 'YYYY-MM-DD') start_date, 
    to_date('2014-04-04', 'YYYY-MM-DD') end_date from dual 
    union all 
    select 3 rate_id, 'big' rate, 300 charge, 
    to_date('2014-04-05', 'YYYY-MM-DD') start_date, 
    to_date('2014-12-31', 'YYYY-MM-DD') end_date from dual 
) 
select sum(charge) as total_charge from (
    select d.*, r.* from v_days d 
    join v_rates r on d.dt >= r.start_date and d.dt <= r.end_date 
    order by d.dt 
) 

說明:

  • v_days生成開始日期和結束日期之間的天數列表(每天一行)
  • v_rates只包含你給
  • ,我們再加入兩個子查詢率 - 給定日期所屬的速度,如果它是速度
  • 在最後的開始和結束日期之間,我們只是總結了費用得到總費用
+0

是啊..通過它.. ..謝謝弗蘭克;) – ajmalmhd04

0

DATEDIFF()函數返回兩個日期之間的時間。

SELECT DATEDIFF(day,'01-01-2014','31-03-2014') AS DiffDate 

並考慮日期格式以獲得正確的結果。

請參考以下鏈接瞭解更多信息 http://www.w3schools.com/sql/func_datediff.asp

+0

這是一個SQL服務器功能,而問題是標記爲Oracle。 –

+0

@tarzanbappa,這不是答案。這只是獲得日期差異。 –

+0

他問:「是否有任何簡單的方法來查找給定範圍內存在的天數」。 – tarzanbappa

0
select sum(case 
      when trunc(&start_date) <= trunc("to_date") AND 
        trunc(&end_date) >= trunc(from_date) then 
       (least(trunc(&end_date), trunc("to_date")) - 
       greatest(trunc(&start_date), trunc(from_date)) + 1) * charge 
      else 
       0 
      end) total_charge 
    from your_table; 

最簡單的方法是找到,如果你start_dateend_date跨越特定時期(when部分在case)的邊界,然後計算兩個日期賦予的區別你nu幾天(+1是必要的,考慮開始日期和結束日期是否相同,你仍然需要收取1天),然後乘以相應的費用。

如果用日期範圍表較大,則考慮將case條件where

select sum((least(trunc(&end_date), trunc("to_date")) - 
      greatest(trunc(&start_date), trunc(from_date)) + 1) 
      * charge) total_charge 
    from your_table 
where trunc(&start_date) <= trunc("to_date") 
    AND trunc(&end_date) >= trunc(from_date); 

你寧可不要,只要有相同名稱的轉換函數中使用列名「TO_DATE」。

+0

謝謝.lemme學習它:) – ajmalmhd04

0
with w as (
    select 100 charge, date '2014-01-01' from_date, date '2014-03-31' to_date from dual union all 
    select 200 charge, date '2014-04-01' from_date, date '2014-04-04' to_date from dual union all 
    select 300 charge, date '2014-04-05' from_date, date '2014-12-31' to_date from dual 
), 
x as (
    select 
    date '2014-03-30' start_period, 
    date '2014-04-05' end_period 
    from 
    dual 
) 
select 
sum(
    w.charge * 
    case when x.start_period <= w. to_date and 
       x. end_period >= w.from_date 
    then 
     case when x.end_period > w.to_date 
      then w.to_date 
      else x.end_period 
     end 
      - 
     case when x.start_period < w.from_date 
      then w.from_date 
      else x.start_period 
     end 
     +1 
    else 
     0 
    end 
) result 
from 
    w cross join x; 
+0

表似乎很簡單..但有交叉連接,所以lemme學習它:) ..無論如何感謝勒內 – ajmalmhd04

0

AND TO_DATE(SYSDATE, '日/月/年')BETWEEN TO_DATE(SYSDATE, '日/月/年')AND TO_DATE(END_DATE, '日/月/年') AND TO_DATE( START_DATE,'dd/mm/yyyy')< = TO_DATE(SYSDATE,'dd/mm/yyyy');