Home » SQL & PL/SQL » SQL & PL/SQL » Volume Apportioned to right volumen bands (Oracle 11g)
Volume Apportioned to right volumen bands [message #648582] Thu, 25 February 2016 15:51 Go to next message
razasheikh
Messages: 11
Registered: February 2016
Location: sdfdf
Junior Member

Hi Experts,

I have an issue with a logic that i tried to resolved but unsuccessful.....

I have daily source volume that need to be apportioned correctly to its volume bands, such that right charges can be applied

Source table Structure:

Create table DAILY_VOL (
CTR Varchar2(10),
YEAR_MONTH Varchar2(10)
);

Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');
Insert into DAILY_VOL values ('T1', '201602');

Look up tables structure:

Create TABLE Unit_Charges (
CTR Varchar2(10),
VOL_BAND number,
MIN_VOL number,
MAX_VOL number,
Charges number
);

Insert into Unit_Charges values ('T1', 1, 1, 10, 100;
Insert into Unit_Charges values ('T1', 2, 11, 20, 10);
Insert into Unit_Charges values ('T1', 3, 21, 30, 5);
Insert into Unit_Charges values ('T1', 3, 31, 40, 2);



Suppose that there are thirty-five (35) transactions for a type T1 in a month and that the volume bands are as defined by the minimum and maximum volumes.

Then the total Charge is calculated by multiplying the volume of transaction within each band by the relevant Unit Price.

Final out come expected:

Band Min Max Charges Volume VolumeCharge
Vol Vol
1 1 10 £100.00 10 £1,000.00
(£100 x 10)
2 11 20 £10.00 10 £100.00
(£10 x10)
3 21 30 £5.00 10 £50.00
(£5 x 10)
4 31 40 £2.00 5 £10.00
(£2 x 5)
Total 35 £1,160.00

I had done few quires with analytical functions using Range Between Min_Vol FOLLOWING AND UNBOUNDED FOLLOWING


But nothing workout ....


Highly appropriate you help on this .

Thank you
Re: Volume Apportioned to right volumen bands [message #648585 is a reply to message #648582] Thu, 25 February 2016 18:56 Go to previous messageGo to next message
Barbara Boehmer
Messages: 9088
Registered: November 2002
Location: California, USA
Senior Member
SCOTT@orcl> -- test data:
SCOTT@orcl> SELECT ctr, year_month, COUNT(*)
  2  FROM   daily_vol
  3  GROUP  BY ctr, year_month
  4  /

CTR        YEAR_MONTH   COUNT(*)
---------- ---------- ----------
T1         201602             35

1 row selected.

SCOTT@orcl> SELECT * FROM unit_charges
  2  /

CTR          VOL_BAND    MIN_VOL    MAX_VOL    CHARGES
---------- ---------- ---------- ---------- ----------
T1                  1          1         10        100
T1                  2         11         20         10
T1                  3         21         30          5
T1                  4         31         40          2

4 rows selected.

SCOTT@orcl> -- query:
SCOTT@orcl> SELECT dv.ctr, dv.year_month,
  2  	    uc.vol_band "Band", uc.min_vol "Min", uc.max_vol "Max", uc.charges "Charges",
  3  	    COUNT(*) "Volume", COUNT(*) * charges "VolumeCharge"
  4  FROM   (SELECT ctr, year_month,
  5  		    ROW_NUMBER () OVER (PARTITION BY ctr, year_month ORDER BY ROWID) rn
  6  	     FROM   daily_vol) dv,
  7  	     unit_charges uc
  8  WHERE  dv.ctr = uc.ctr
  9  AND    dv.rn BETWEEN uc.min_vol AND uc.max_vol
 10  GROUP  BY dv.ctr, dv.year_month,
 11  	    uc.vol_band, uc.min_vol, uc.max_vol, uc.charges
 12  ORDER  BY dv.ctr, dv.year_month, uc.vol_band
 13  /

CTR        YEAR_MONTH       Band        Min        Max    Charges     Volume VolumeCharge
---------- ---------- ---------- ---------- ---------- ---------- ---------- ------------
T1         201602              1          1         10        100         10         1000
T1         201602              2         11         20         10         10          100
T1         201602              3         21         30          5         10           50
T1         201602              4         31         40          2          5           10

4 rows selected.


Re: Volume Apportioned to right volumen bands [message #648606 is a reply to message #648585] Fri, 26 February 2016 10:29 Go to previous messageGo to next message
razasheikh
Messages: 11
Registered: February 2016
Location: sdfdf
Junior Member

Thank you once again Barbara for you kind response...

But my sincere apologies the volume we receive is already exaggerated and we need to literally split that in to different volume bands

sample data

Create TABLE Unit_Charges (
CTR Varchar2(10),
VOL_BAND number,
MIN_VOL number,
MAX_VOL number,
Charges number
);

Insert into Unit_Charges values ('T1', 1, 1, 10, 100;
Insert into Unit_Charges values ('T1', 2, 11, 20, 10);
Insert into Unit_Charges values ('T1', 3, 21, 30, 5);
Insert into Unit_Charges values ('T1', 3, 31, 40, 2);

Create table DAILY_VOL (
CTR Varchar2(10),
YEAR_MONTH Varchar2(10),
Volume number
);

Insert into DAILY_VOL values ('T1', '201602',57);
Insert into DAILY_VOL values ('T1', '201603',4);

The unit charges stays that same but the daily volume is aggregated and this need to be apportioned

example out of 57 in feb 2016 10 should be approached to band 1 (1- 10)
and next range that is 11 - 20 in band 2 ... so on...

would highly appreciate if you can help me on this tooo...

Thank you
Re: Volume Apportioned to right volumen bands [message #648607 is a reply to message #648606] Fri, 26 February 2016 14:00 Go to previous messageGo to next message
Barbara Boehmer
Messages: 9088
Registered: November 2002
Location: California, USA
Senior Member
SCOTT@orcl> -- test data:
SCOTT@orcl> SELECT * FROM daily_vol
  2  /

CTR        YEAR_MONTH     VOLUME
---------- ---------- ----------
T1         201602             57
T1         201603              4

2 rows selected.

SCOTT@orcl> SELECT * FROM unit_charges
  2  /

CTR          VOL_BAND    MIN_VOL    MAX_VOL    CHARGES
---------- ---------- ---------- ---------- ----------
T1                  1          1         10        100
T1                  2         11         20         10
T1                  3         21         30          5
T1                  4         31         40          2

4 rows selected.

SCOTT@orcl> -- query:
SCOTT@orcl> SELECT dv.ctr, dv.year_month,
  2  	    uc.vol_band "Band", uc.min_vol "Min", uc.max_vol "Max", uc.charges "Charges",
  3  	    COUNT(*) "Volume", COUNT(*) * charges "VolumeCharge"
  4  FROM   (SELECT ctr, year_month, COLUMN_VALUE rn
  5  	     FROM   daily_vol,
  6  		   TABLE
  7  		     (CAST
  8  			(MULTISET
  9  			   (SELECT LEVEL
 10  			    FROM   DUAL
 11  			    CONNECT BY LEVEL <= volume)
 12  			 AS SYS.ODCINUMBERLIST))) dv,
 13  	     unit_charges uc
 14  WHERE  dv.ctr = uc.ctr
 15  AND    dv.rn BETWEEN uc.min_vol AND uc.max_vol
 16  GROUP  BY dv.ctr, dv.year_month,
 17  	    uc.vol_band, uc.min_vol, uc.max_vol, uc.charges
 18  ORDER  BY dv.ctr, dv.year_month, uc.vol_band
 19  /

CTR        YEAR_MONTH       Band        Min        Max    Charges     Volume VolumeCharge
---------- ---------- ---------- ---------- ---------- ---------- ---------- ------------
T1         201602              1          1         10        100         10         1000
T1         201602              2         11         20         10         10          100
T1         201602              3         21         30          5         10           50
T1         201602              4         31         40          2         10           20
T1         201603              1          1         10        100          4          400

5 rows selected.


Re: Volume Apportioned to right volumen bands [message #648636 is a reply to message #648607] Sat, 27 February 2016 11:59 Go to previous messageGo to next message
razasheikh
Messages: 11
Registered: February 2016
Location: sdfdf
Junior Member

Thank you once again .... this is really appreciated.

I believe I am doing bit wrong here used your query and tired to change this with my real data set, but is am getting wrong results

SELECT dv.ctr, dv.MONTH_WID,
uc.VOLUME_BAND "Band", uc.MIN_VOLUME "Min", uc.MAX_VOLUME "Max", uc.UNIT_PRICE "Charges",
COUNT(*) "Volume", COUNT(*) * UNIT_PRICE "VolumeCharge"
FROM (SELECT COMMAND_TYPE,PRIORITY_CODE,CTR, MONTH_WID, COLUMN_VALUE rn
FROM (SELECT A.COMMAND_TYPE,A.PRIORITY_CODE, A.CTR, C.ROW_WID AS MONTH_WID,B.MSG_COUNT
FROM SMODS.ODS_MTR A JOIN SMODS.ODS_MTS_DV B ON (A.ROW_WID=B.MTR_WID)
JOIN SMDWH.W_MONTH_D C ON (TO_NUMBER(TO_CHAR(B.GW_TIMESTAMP_DAY,'YYYYMM'))=C.ROW_WID)
WHERE CTR= 'T1'
) Daily_VOL ,
TABLE
(CAST
(MULTISET
(SELECT LEVEL
FROM DUAL
CONNECT BY LEVEL <= MSG_COUNT)
AS SYS.ODCINUMBERLIST))) dv,
SMDWH.wc_mtr_unit_chg_d uc
WHERE dv.ctr = uc.ctr
AND dv.rn BETWEEN uc.MIN_VOLUME AND uc.MAX_VOLUME
GROUP BY dv.ctr, dv.MONTH_WID,uc.VOLUME_BAND, uc.MIN_VOLUME, uc.MAX_VOLUME, uc.UNIT_PRICE
ORDER BY dv.ctr, dv.MONTH_WID, uc.VOLUME_BAND
/

Basically the 'daily_vol' source that I shared comes from three different tables (subquery - highlighted in orange) and that's not working right

I had even tried to use With clause / Global temporary table option even that not working as expected.

highly appreciate your help again - I am not feeling good about coming back again and again, but honestly I am completely blocked.


thank you
Re: Volume Apportioned to right volumen bands [message #648637 is a reply to message #648636] Sat, 27 February 2016 12:26 Go to previous messageGo to next message
razasheikh
Messages: 11
Registered: February 2016
Location: sdfdf
Junior Member

Sorry that was my mistake completely forgot to group the data ....

Thank you so much for your help.
Re: Volume Apportioned to right volumen bands [message #648638 is a reply to message #648637] Sat, 27 February 2016 12:31 Go to previous message
BlackSwan
Messages: 26766
Registered: January 2009
Location: SoCal
Senior Member
Please read and follow the forum guidelines, to enable us to help you:
OraFAQ Forum Guide
How to use {code} tags and make your code easier to read
Previous Topic: character string buffer too small error in function
Next Topic: String Printing by PL/SQL code?
Goto Forum:
  


Current Time: Thu Apr 18 21:57:01 CDT 2024