|
就算这样,CONNECT BY也算不出来,中间的重复太多了。
PL/SQL做法:其实就是把我那个递归写法拆散,每层建立一个临时表而已,但是这样就快了很多。递归SQL还是不够聪明。
VAR N NUMBER;
EXEC :N:=4;
create table e (b number,b2 number);
insert into e
WITH
d as (select power(2,level) n,ceil(level/:N) x,mod(level,:N) y from dual connect by level<=:N*:N)
select power(2,rownum-1) b,p1.n+p2.n b2
from d p1,d p2
where abs(p1.x - p2.x) + abs(p1.y-p2.y) =1 and p1.n < p2.n
;
create table e1_12 as
with
t (b,b2,rn,lvl) as (
select b,b2,1,1 from e
union all
select t.b+e.b
,t.b2+e.b2-bitand(t.b2,e.b2) --- bitor
,row_number() over(partition by t.b+e.b order by 1) rn
,lvl+1
from t,e
where t.rn=1 ------- 去重复
and bitand(t.b,e.b)=0
and bitand(t.b2,e.b2)>0
and lvl<12
)
select distinct b,b2,lvl from t;
Elapsed: 00:01:09.17
create table e12 as select b,b2 from e1_12 where lvl=12;
begin
for i in 13..24 loop
execute immediate 'drop table e'||i;
execute immediate '
create table e'||i||' as
select distinct t.b+e.b b
,t.b2+e.b2-bitand(t.b2,e.b2) b2
from e'||(i-1)||' t,e
where bitand(t.b,e.b)=0
and bitand(t.b2,e.b2)>0
';
end loop;
end;
/
PL/SQL procedure successfully completed.
Elapsed: 00:00:23.87
|
|