LEVEL Parent Chile Parent Qty Child Qty
1 A B 1 3
2 B C 2 3
3 C D 5 6
4 D E 1 2
1 A Z 1 3
A是成品
B,C,D是半成品
E,Z是原材料
从上面一个比例关系可以计算出,做一个A最终需要10.8个E和3个Z,我想知道有没有什么办法通过一个SQL语句来实现这个功能。
请大家帮忙想象办法。
[ 本帖最后由 lypch 于 2008-7-11 21:52 编辑 ]

最新回复
lypch (2008-7-11 11:15:04)
coltsu (2008-7-14 15:03:07)
select 1||sys_connect_by_path(child_qty/parent_qty,'*') From table_name start with chile='E' connect by chile=prior parent;
运行结果:
1*2
1*2*1.2
1*2*1.2*1.5
1*2*1.2*1.5*3
1*2*1.2*1.5*3=10.8
yzsind (2008-7-15 10:27:10)
(
MYLEVEL NUMBER,
PARENT VARCHAR2(1),
CHILD VARCHAR2(1),
PARENT_QTY NUMBER,
CHILD_QTY NUMBER
)
;
insert into TEST6 (MYLEVEL, PARENT, CHILD, PARENT_QTY, CHILD_QTY)
values (1, 'A', 'B', 1, 3);
insert into TEST6 (MYLEVEL, PARENT, CHILD, PARENT_QTY, CHILD_QTY)
values (2, 'B', 'C', 2, 3);
insert into TEST6 (MYLEVEL, PARENT, CHILD, PARENT_QTY, CHILD_QTY)
values (3, 'C', 'D', 5, 6);
insert into TEST6 (MYLEVEL, PARENT, CHILD, PARENT_QTY, CHILD_QTY)
values (4, 'D', 'E', 1, 2);
insert into TEST6 (MYLEVEL, PARENT, CHILD, PARENT_QTY, CHILD_QTY)
values (1, 'A', 'E', 1, 3);
commit;
SQL> select substr(p, 1, decode(instr(p, '/', 2), 0, 100, instr(p, '/', 2) - 1)) N,
2 exp(SUM(ln(CHILD_QTY / PARENT_QTY))) V
3 from (select CHILD_QTY,
4 PARENT_QTY,
5 SYS_CONNECT_BY_PATH(PARENT || '-' || CHILD, '/') P
6 from test6 a
7 start with mylevel = 1
8 connect by PRIOR child = parent)
9 group by substr(p,
10 1,
11 decode(instr(p, '/', 2), 0, 100, instr(p, '/', 2) - 1))
12 ;
N V
-------------------------------------------------------------------------------- ----------
/A-B 10.8
/A-E 3
SQL>
yzsind (2008-7-15 10:28:48)
http://yangtingkun.itpub.net/post/468/466388
做了一点小的调整
yzsind (2008-7-15 11:38:19)
建议楼主还是采用PL/SQL或者是其它程序言去实现吧,这样可靠性及可读性及可维护性会好得多。
yzsind (2008-7-15 15:18:32)
create table TEST6
(
MYLEVEL NUMBER,
PARENT VARCHAR2(10),
CHILD VARCHAR2(10),
PARENT_QTY NUMBER,
CHILD_QTY NUMBER
)
;
insert into TEST6 (MYLEVEL, PARENT, CHILD, PARENT_QTY, CHILD_QTY)
values (1, 'A', 'B', 1, 3);
insert into TEST6 (MYLEVEL, PARENT, CHILD, PARENT_QTY, CHILD_QTY)
values (2, 'B', 'C', 2, 3);
insert into TEST6 (MYLEVEL, PARENT, CHILD, PARENT_QTY, CHILD_QTY)
values (3, 'C', 'D', 5, 6);
insert into TEST6 (MYLEVEL, PARENT, CHILD, PARENT_QTY, CHILD_QTY)
values (4, 'D', 'E', 1, 2);
insert into TEST6 (MYLEVEL, PARENT, CHILD, PARENT_QTY, CHILD_QTY)
values (1, 'A', 'Z', 1, 3);
insert into TEST6 (MYLEVEL, PARENT, CHILD, PARENT_QTY, CHILD_QTY)
values (4, 'D', 'F', 1, 3);
insert into TEST6 (MYLEVEL, PARENT, CHILD, PARENT_QTY, CHILD_QTY)
values (3, 'C', 'F', 2, 3);
insert into TEST6 (MYLEVEL, PARENT, CHILD, PARENT_QTY, CHILD_QTY)
values (2, 'B', 'D', 1, 1.5);
commit;
--临时表,用来保存计算结果
create global temporary table TEMP_TEST6
(
PARENT VARCHAR2(10),
CHILD VARCHAR2(10),
QTY NUMBER
)
on commit preserve rows;
yzsind (2008-7-15 15:19:53)
create or replace procedure CalcBOM(iPName varchar2) is
vCnt int;
procedure getvalue(iParent varchar2, iQty number) as
cursor cur_test6(iParent varchar2) is
select * from test6 where parent = iParent;
begin
select count(*) into vCnt from test6 where parent = iParent;
if vCnt = 0 then
insert into temp_test6
(parent, child, qty)
values
(iPName, iParent, iQty);
dbms_output.put_line('iParent:' || iParent || ';iValue:' || iQty);
else
for v_rec in cur_test6(iParent) loop
getvalue(v_rec.child, iQty * v_rec.child_qty / v_rec.Parent_Qty);
end loop;
end if;
end;
begin
delete from temp_test6;
getvalue(iPName, 1);
end CalcBOM;
yzsind (2008-7-15 15:25:42)
SQL> select * from test6;
MYLEVEL PARENT CHILD PARENT_QTY CHILD_QTY
---------- ---------- ---------- ---------- ----------
1 A B 1 3
2 B C 2 3
3 C D 5 6
4 D E 1 2
1 A Z 1 3
4 D F 1 3
3 C F 2 3
2 B D 1 1.5
8 rows selected
SQL> exec CalcBOM('A');
PL/SQL procedure successfully completed
SQL> select parent,child,sum(qty) qty from temp_test6 group by parent,child;
PARENT CHILD QTY
---------- ---------- ----------
A E 19.8
A F 36.45
A Z 3
SQL>
SunnyXu (2008-7-15 17:47:17)
存储过程或函数实现不是也很好吗? 这样更容易实现。