I wonder if there is any way to generate Fibonacci numbers that beat in simplicity and efficiency this one I wrote:
WITH d (seq) AS
       (SELECT     LEVEL
        FROM       DUAL
        CONNECT BY LEVEL < 195)
SELECT   seq
        ,fib
FROM     d
MODEL
  DIMENSION BY(seq)
  MEASURES(0 AS fib)
  RULES
    (fib [1] = 0,
    fib [2] = 1,
    fib [seq BETWEEN 3 AND 194] = fib[CV(seq) - 2] + fib[CV(seq) - 1],
    fib [seq > 194] = NULL)
ORDER BY 1
/
Execution Plan
----------------------------------------------------------
Plan hash value: 2245903385
---------------------------------------------------------------------------------------
| Id  | Operation                      | Name | Rows  | Bytes | Cost (%CPU)| Time     |
---------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT               |      |     1 |    13 |     2   (0)| 00:00:01 |
|   1 |  SQL MODEL ORDERED             |      |     1 |    13 |            |          |
|   2 |   VIEW                         |      |     1 |    13 |     2   (0)| 00:00:01 |
|*  3 |    CONNECT BY WITHOUT FILTERING|      |       |       |            |          |
|   4 |     FAST DUAL                  |      |     1 |       |     2   (0)| 00:00:01 |
---------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   3 - filter(LEVEL<195)
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          0  consistent gets
          0  physical reads
          0  redo size
       4798  bytes sent via SQL*Net to client
        500  bytes received via SQL*Net from client
         14  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
        194  rows processed
SQL>
Note: LEVEL < 195 was not arbitrarily chosen, higher values make the algorithm lose precision so I decided not to include them in order to keep correct results only.
on the simplicity side of things, the query can rely on the built in features (ITERATE () and ITERATION_NUMBER) of MODEL:
select * from dual
model
  dimension by (0 seq)
  measures (0 val)
  rules iterate (195) 
  (
     val[iteration_number] = val[iteration_number-1] + val[iteration_number-2],
     val[2] = 1, 
     val[1] = 0, 
     val[0] = 0
  )
;
    You can use a recursive sub-query factoring clause:
WITH fib ( lvl, value, next ) AS (
  SELECT 1, 0, 1
  FROM DUAL
UNION ALL
  SELECT lvl + 1, next, value + next
  FROM fib
  WHERE lvl < 195
)
SELECT lvl, value FROM fib
    Something like this should be (much?) faster:
with
     constants ( x, y, z ) as (
       select 0.5 * ( 1 + sqrt(5) ),
              0.5 * ( 1 - sqrt(5) ),
              sqrt(5)
       from   dual
     )
select level as seq, round( ( power(x, level - 1) - power(y, level - 1) ) / z ) as fib
from   constants
connect by level < 195
;
The point being, you don't need to use the recursive formula; the terms can be written in closed form. Since computers can't do arithmetic with real numbers, only with rational number approximations, I needed to add a ROUND(...) but even so this should be faster than recursive approaches.
EDIT: At the OP's request I traced the execution of this code. I don't see the recursive calls the OP is referring to in the Comment below.
Execution Plan
----------------------------------------------------------
Plan hash value: 1236776825
-----------------------------------------------------------------------------
| Id  | Operation                    | Name | Rows  | Cost (%CPU)| Time     |
-----------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |      |     1 |     2   (0)| 00:00:01 |
|*  1 |  CONNECT BY WITHOUT FILTERING|      |       |            |          |
|   2 |   FAST DUAL                  |      |     1 |     2   (0)| 00:00:01 |
-----------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
   1 - filter(LEVEL<195)
Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
          0  consistent gets
          0  physical reads
          0  redo size
       6306  bytes sent via SQL*Net to client
        684  bytes received via SQL*Net from client
         14  SQL*Net roundtrips to/from client
          1  sorts (memory)
          0  sorts (disk)
        194  rows processed
EDIT #2
I suspect the simple generation of levels in a recursive query may be expensive. It's possible that a cross-join of similarly generated, but smaller sequences of integers may work a bit faster. The code looks more complicated (of course); the only change, though, is the way I generate the powers.
with
     constants ( x, y, z ) as (
       select 0.5 * ( 1 + sqrt(5) ),
              0.5 * ( 1 - sqrt(5) ),
              sqrt(5)
       from   dual
     ),
     powers ( n ) as (
       select 14 * a.p + b.q
       from   (select level - 1 p from dual connect by level <= 14) a
              cross join
              (select level - 1 q from dual connect by level <= 14) b
     )
select n + 1 as seq, round( ( power(x, n) - power(y, n) ) / z ) as fib
from   constants cross join powers
where  n < 195
;
    来源:https://stackoverflow.com/questions/44415801/any-better-fibonacci-series-generator-using-pure-oracle-sql