sql >> Database teknologi >  >> RDS >> Oracle

Beregning af beholdningsgennemsnitlige omkostninger i SQL

Du kan bruge MODEL-sætningen til at udføre denne rekursive beregning

Opret eksempeltabel og indsæt data

opret tabelomkostninger (ordre_id int, volume int, price numeric(16,4), type char(1));insert into cost (order_id, volume, price) values ​​(1.1000.100); indsæt i omkostninger (ordre_id, volume, price) værdier (2,-500,110);indsæt i omkostninger (ordre_id, volume, price) værdier (3,1500,80);indsæt i omkostninger (ordre_id, volume, price) værdier (4) ,-100.150);indsæt i omkostninger (ordre_id, volume, price) værdier (5,-600.110);indsæt i omkostninger (ordre_id, volume, price) værdier (6.700.105); 

Forespørgslen (REDIGERT ændre regler iterate(1000) til regler automatisk rækkefølge implementerer MODEL-klausulen, som den er beregnet til at fungere, dvs. top til bund sekventielt. Det tog også forespørgslen fra 0,44s til 0,01s!)

vælg ordre-id, volumen, pris, total_vol, total_costs, unit_costs from (vælg ordre_id, volumen, pris, volumen total_vol, 0,0 total_costs, 0,0 unit_costs, row_number() over (ordre by order_id) rn fra omkostninger ordre pr. ordre_id) modeldimension efter (ordre_id) mål (volumen, pris, total_vol, total_costs, unit_costs) regler automatisk ordre -- iterate(1000) ( total_vol[enhver] =volumen[cv()] + nvl(total_vol[cv()- 1],0.0), total_costs[any] =case SIGN(volume[cv()]) når -1 derefter total_vol[cv()] * nvl(unit_costs[cv()-1],0.0) else volume[cv( )] * pris[cv()] + nvl(total_costs[cv()-1],0.0) end, unit_costs[any] =total_costs[cv()] / total_vol[cv()] ) bestil efter ordre-id 

Output

meget

Dette websted har en god vejledning om MODEL-klausulen

  • http://www.sqlsnippets.com/en/topic-11663.html

EXCEL-arket for dataene ovenfor ville se sådan ud, med formlen udvidet nedad
 A B C D E F -------------------------- --------------------------------------------------1 | ordre_id volumenpris total_vol total_costs unit_costs2| 0 0 03| 1 1000 100 =C4+E3 =IF(C4<0,G3*E4,F3+C4*D4) =F4/E44| 2 -500 110 =C5+E4 =IF(C5<0,G4*E5,F4+C5*D5) =F5/E55| 3 1500 80 =C6+E5 =IF(C6<0,G5*E6,F5+C6*D6) =F6/E66| 4 -100 150 =C7+E6 =IF(C7<0,G6*E7,F6+C7*D7) =F7/E77| 5 -600 110 =C8+E7 =IF(C8<0,G7*E8,F7+C8*D8) =F8/E88| 6 700 105 =C9+E8 =IF(C9<0,G8*E9,F8+C9*D9) =F9/E9 


  1. How to_timestamp() virker i PostgreSQL

  2. Konverter et resultatsæt fra SQL Array til Array of Strings

  3. SQL Server Database Change Listener C#

  4. Optimal måde at sammenkæde/samle strenge