已解决:请教 :上下记录有逻辑关系的数据如何按顺序排序(10G)
本帖最后由 hnweicr 于 2010-11-19 20:28 编辑比如 字段为 AB C三者之间的关系是: C=A+B
而且 上一记录的C 等于下一记录的A
我想按这种逻辑关系把数据进行排序,发现很难。
用connect byprior也试不出来,请各位帮忙下
create table prior_test (a number(4),b number(4),c number(4));
insert into prior_test values(110,-110,0);
insert into prior_test values(100,-100,0);
insert into prior_test values(0,110,110);
insert into prior_test values(0,100,100);
commit;
已知道这四条记录之前的记录 为 5 -5 0
已知道这四条记录之后的记录为 0 10000 10000
希望得出这样的顺序
5 -5 0
0 100 100
100 -100 0
0 110 110
110 -110 0
0 10000 10000
或者是
5 -5 0
0 110 110
110 -110 0
0 100 100
100 -100 0
0 10000 10000
均可. :em27: 看来要用递归算法或是穷举算法写个过程或函数才行。
有熟悉oracle递归的朋友能否帮忙写一个。 本帖最后由 hnweicr 于 2010-11-20 00:12 编辑
回复 1# hnweicr
今天有空,研究了一下oracleselect * from tab connect by prior start with的用法,发现怎么用都得不到我想要的,
也许是我自己笨,搞不掂而已。不熟oracle的递归算法,于是用穷举,有点傻但至少能解决问题。(还没优化,可能有bug)
希望其他朋友能有更好的方法。DECLARE
-----在此只考虑处理表中的数据,也就是说,不考虑表中数据 之前记录的C 及之后记录的A
-----我只是算表中的数据头尾相连起来应有的几套方案。只要再把之前的C及之后的A传进来即可得到想要的方案(可能是多套)
-----代码只考虑一个用户在同一时间有少于10笔的情况超过10笔的情况尚需再改
CURSOR get_all IS
SELECT abalance, c as my_left
FROM prior_test
;
------------------------------------------------------------------
TYPE user_record IS RECORD
( seq NUMBER(10),
balance NUMBER(13,3),
my_left NUMBER(13,3)
);
TYPE user_array ISTABLE OF user_record
INDEX BY BINARY_INTEGER;
------------------------------------------------------------------
record_array user_array; --表中数据数组
test_array user_array; --组合数据测试数组
vn_INDEX NUMBER(3):=0;
vn_start NUMBER(18):=0;--排列起点数
vn_end NUMBER(18):=0;--排列终点
vn_count NUMBER(18):=0;
vn_number NUMBER(1):=0;
test_ok NUMBER(10):=0;
BEGIN
FOR i IN get_all
LOOP
vn_INDEX:=vn_INDEX+1;
record_array(vn_INDEX).seq:=vn_INDEX;
record_array(vn_INDEX).balance:=i.balance;
record_array(vn_INDEX).my_left:=i.my_left;
END LOOP;
FOR i IN1..record_array.COUNT
LOOP
vn_start:=vn_start+i*power(10,(record_array.COUNT-i));--比如6行数的话就是123456
END LOOP;
------------------------------------------------------------------
FOR i INREVERSE 1..record_array.count ---654321
LOOP
vn_end:=vn_end+i*power(10,(i-1));
END LOOP;
FOR i IN vn_start..vn_end
LOOP--主要是取得所有数据排列有多少种可能 ,数据中含有123456各位数且不重复的均符合
vn_count:=0;
FOR j INREVERSE 1..record_array.COUNT
LOOP
vn_number:=0;
vn_number:=TO_NUMBER(SUBSTR(TO_CHAR(i),j,1));
IF ( vn_number=0 OR vn_number>record_array.COUNT OR instr(TO_CHAR(i),TO_CHAR(vn_number),1,2)>0) THEN
EXIT;
END IF;
vn_count:=vn_count+1;
END LOOP;
IF vn_count=record_array.COUNT THEN
FOR j IN 1..record_array.COUNT
LOOP
test_array(j):=record_array(TO_NUMBER(SUBSTR(TO_CHAR(i),j,1)));
END LOOP;
------------------------------------------------------------------
test_ok:=0; --排列顺序数据是否符合逻辑关系
FOR j IN 1..record_array.COUNT-1
LOOP
IF (test_array(TO_NUMBER(j)).my_left<>test_array(TO_NUMBER(j)+1).balance) THEN
EXIT;
END IF;
test_ok:=test_ok+1;
END LOOP;
IFtest_ok=record_array.COUNT-1 THEN--符合逻辑
DBMS_OUTPUT.PUT_LINE(TO_CHAR(i));
FOR j IN 1..record_array.COUNT
LOOP
DBMS_OUTPUT.PUT_LINE (TO_CHAR(test_array(TO_NUMBER(j)).seq)||'***'||TO_CHAR(test_array(TO_NUMBER(j)).balance)||
'***'||TO_CHAR(test_array(TO_NUMBER(j)).my_left));
END LOOP;
END IF;
END IF;
END LOOP;
END;
回复 4# hnweicr
看来想用SQL语句实现比较难。 使用触发器,可以解决
页:
[1]