|
|
把 函数中得 SQL 换掉,要快一点:
SQL>
SQL> with function f (p_v in varchar2)
2 return int
3 is
4 l_adj_sum int :=0;
5 l_cnt int :=0;
6 x int :=0;
7 y int :=0;
8 begin
9 for i in 1..9 loop
10
11 if to_number(substr(p_v,i,1)) > 0 then
12 /*with a(n,x,y) as (select level n,
13 ceil(level/3) x,
14 decode(mod(level,3),0,3,mod(level,3)) y
15 from dual
16 connect by level<=9)
17 select sum(to_number(substr(p_v,a2.n,1)))
18 into l_adj_sum
19 from a a1,a a2
20 where abs(a1.x-a2.x) + abs(a1.y-a2.y) =1
21 and a1.n = i;*/
22
23 x:=ceil(i/3);
24 y:=case when mod(i,3)=0 then 3 else mod(i,3) end;
25
26 l_adj_sum:= case when x-1 between 1 and 3 then substr(p_v,(3*(x-2)+y),1) else 0 end
27 + case when x+1 between 1 and 3 then substr(p_v,(3*x+y),1) else 0 end
28 + case when y-1 between 1 and 3 then substr(p_v,(3*(x-1)+y-1),1) else 0 end
29 + case when y+1 between 1 and 3 then substr(p_v,(3*(x-1)+y+1),1) else 0 end;
30
31 if l_adj_sum > 0 then
32 l_cnt := l_cnt + 1;
33 end if;
34 end if;
35
36 end loop;
37
38 if 9-regexp_count(p_v,0)=l_cnt then
39 return 1;
40 else
41 return 0;
42 end if;
43 end;
44 t(c) as (select level-1 from dual connect by level <= 3+1),
45 s(n,v) as (select 1,cast(c as varchar2(10)) from t
46 union all
47 select n+1,
48 s.v||t.c
49 from s,t
50 where n < 3*3
51 and case when t.c > 0 then
52 case when mod(n+1,3)=1 then
53 case when ceil((n+1)/3) = 1 then 1
54 when ceil((n+1)/3) > 1 and t.c <> substr(s.v,-3,1) then 1
55 else 0
56 end
57 else
58 case when ceil((n+1)/3) = 1 and t.c <> substr(s.v,-1,1) then 1
59 when ceil((n+1)/3) > 1 and t.c <> substr(s.v,-3,1) and t.c <> substr(s.v,-1,1) then 1
60 else 0
61 end
62 end
63 else 1
64 end = 1
65 )
66 select count(v)
67 from s
68 where regexp_count(v,0)=(3*3-(2*3-1))
69 and n=3*3
70 and instr(v,'1')>0
71 and instr(v,'2')>0
72 and instr(v,'3')>0
73 and f(v)=1
74 /
COUNT(V)
----------
2826 |
|