oracle 三列数值相加,Oracle SQL/PLSQL:按货币拆分和求和值的分层查询
恐怕你把大家都搞糊涂了。)
雖然你的要求部分難以理解,但我認為如果我必須處理這類任務,我會做一件事。我將編寫遞歸函數,計算從樹的任何部分到葉的成本。
以下是與您類似的數據演示:
select prod.*, level, sys_connect_by_path(seq, '->') path,
calc_cost(comp) total
from prod connect by prior comp = part
start with base = 1;
SEQ PART COMP QTY COST CURR BASE AFO RFO LEVEL PATH TOTAL
------ ---- ---- ---------- ---------- ---- ---------- --- --- ------- ----------- ----------
1 A A1 5 1 1 ->1 850
2 A1 A11 3 0 B 2 ->1->2 114
3 A11 A111 4 2 EUR 0 B;D 3 ->1->2->3 8
4 A11 A112 2 15 EUR 0 3 ->1->2->4 30
5 A1 A12 8 7 EUR 0 2 ->1->5 56
11 B B1 5 1 1 ->11 870
12 B1 B11 3 0 2 ->11->12 174
13 B11 B111 4 12 GBP 0 3 ->11->12->13 48
14 B11 B112 2 5 GBP 0 3 ->11->12->14 10
柱
total
包含組件成本,例如
B1
它是
5 * (3 * (4 * 12 + 2 * 5))
哪個是
870
.
函數和示例數據如下:
create or replace function calc_cost(i_comp in varchar2) return number is
v_qty number := 0;
v_cost number := 0;
begin
select qty, cost into v_qty, v_cost from prod where comp = i_comp;
if v_cost is null then
select sum(calc_cost(comp)) into v_cost from prod where part = i_comp;
end if;
return v_qty * v_cost;
exception when no_data_found then
return 0;
end;
數據:
create table prod(seq, part, comp, qty, cost, curr, base, afo, rfo) as (
select 1, 'A', 'A1', 5, null, null, 1, null, null from dual union all
select 2, 'A1', 'A11', 3, null, null, 0, 'B', null from dual union all
select 3, 'A11', 'A111', 4, 2, 'EUR', 0, null, 'B;D' from dual union all
select 4, 'A11', 'A112', 2, 15, 'EUR', 0, null, null from dual union all
select 5, 'A1', 'A12', 8, 7, 'EUR', 0, null, null from dual union all
select 11, 'B', 'B1', 5, null, null, 1, null, null from dual union all
select 12, 'B1', 'B11', 3, null, null, 0, null, null from dual union all
select 13, 'B11', 'B111', 4, 12, 'GBP', 0, null, null from dual union all
select 14, 'B11', 'B112', 2, 5, 'GBP', 0, null, null from dual );
您沒有指定相同的貨幣是否可以有不同的貨幣
part
/
component
如果是這樣的話,輸出會是怎樣的。不管怎樣,你可以找到這些貨幣,然后獨立地計算每種貨幣。您需要向函數添加第二個參數,并編寫類似
where part = i_comp and curr = i_curr or curr is null
.
也適用于
ask_for_option
/
remove_for_option
你也許可以在
case when
.
我看到你在這個問題上付出了很大的努力,但在目前的問題形式下,很難更好地回答。您應該提供示例數據,而不僅僅是圖像,并根據用戶的選擇向我們準確顯示您期望的輸出。
但我希望這個函數可以幫助您解決這個問題。我假設如果
cost
不為空,則我們位于葉中,否則函數將遞歸查找子組件。
編輯:
假設seq=14是歐元而不是英鎊。
update prod set curr = 'EUR' where seq = 14;
正如我所說,精確的解決方案取決于您需要的輸出。如果您知道所有可能的貨幣,那么您可以修改函數來處理貨幣和顯示成本,如下所示:
create or replace function calc_cost(i_comp in varchar2, i_curr in varchar2)
return number is
v_qty number := 0;
v_cost number := 0;
begin
select qty, cost into v_qty, v_cost from prod
where comp = i_comp and (curr = i_curr or curr is null);
if v_cost is null then
select sum(calc_cost(comp, i_curr)) into v_cost
from prod where part = i_comp and (curr = i_curr or curr is null);
end if;
return v_qty * nvl(v_cost, 0);
exception when no_data_found then
return 0;
end;
select seq, part, comp, qty, cost, curr,
calc_cost(comp, 'EUR') eur, calc_cost(comp, 'GBP') gbp
from prod
connect by part = prior comp
start with part = 'B';
SEQ PART COMP QTY COST CURR EUR GBP
----- ---- ---- ---------- ---------- ---- ---------- ----------
11 B B1 5 150 720
12 B1 B11 3 30 144
13 B11 B111 4 12 GBP 0 48
14 B11 B112 2 5 EUR 10 0
部分
B
成本為150歐元和720英鎊。
您可以在數據的有趣部分中找到所有不同的貨幣,將它們與表連接起來,然后這樣調用函數。結果是每個人
seq
你可以得到和不同貨幣一樣多的行。然后你可以用
listagg()
和現值
150 EUR; 720 GBP
在一個單元格中。
您還可以創建一些類型對象并修改函數,以返回元組表(貨幣,成本單位為歐元)。問題是您希望如何顯示數據。或者可以將值轉換為通用貨幣,但為此需要每日的比率表。
總結
以上是生活随笔為你收集整理的oracle 三列数值相加,Oracle SQL/PLSQL:按货币拆分和求和值的分层查询的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: cas 连接oracle,Oracle
- 下一篇: oracle数据库切换教程,oracle