Możliwe?? Tak, wystarczy polubić klauzulę model..
Poniżej w dwóch zapytaniach są algorytmy zapisane w wersji rekurencyjnej
- ciąg Fibonacciego
- silnia
- algorytm Euklidesa do wyznaczania największego wspólnego podzielnika
- modele iteracyjne -znakomicie nadają się do implementacji jednoargumentowych funkcji rekurencyjnych, a ich zapis jest niemal intuicyjny. Niestety przy większej liczbie parametrów pojawiają się problemy cyklicznego wyliczania komórek
- modele nieiteracyjne - formuły są nieco bardziej zawiłe, ale można obsłużyć funkcje wieloargumentowe
d , f AS FIBBONACCI,
S AS SILNIA
FROM (SELECT 0 d FROM DUAL)
MODEL
DIMENSION BY (0 d)
MEASURES (0 f, 0 s)
RULES
ITERATE (10000000) UNTIL (ITERATION_NUMBER = 50)
(f [ITERATION_NUMBER] =
CASE ITERATION_NUMBER
WHEN 0 THEN 0
WHEN 1 THEN 1
ELSE
f[ITERATION_NUMBER - 2] + f[ITERATION_NUMBER - 1]
END,
s [ITERATION_NUMBER] =
CASE ITERATION_NUMBER
WHEN 0 THEN 1
ELSE
ITERATION_NUMBER * s[ITERATION_NUMBER - 1]
END)
Poniższy przykład można jeszcze nieco uprościć :)
SELECT L1, L2, NWD
FROM (SELECT L1, l2
FROM ( SELECT LEVEL - 1 L1
FROM DUAL
CONNECT BY LEVEL <= 20),
( SELECT LEVEL - 1 L2
FROM DUAL
CONNECT BY LEVEL <= 20))
MODEL
DIMENSION BY (L1, L2)
MEASURES (0 NWD )
RULES SEQUENTIAL ORDER
(NWD [ANY, ANY] =
CASE
WHEN CV (l2) = 0
THEN
CV (l1)
WHEN CV (l2) <= CV (l1)
THEN
NWD[CV (l2), MOD (CV (l1), CV (l2))]
END,
NWD [ANY, ANY] =
CASE
WHEN CV (l2) > CV (l1) THEN
NWD[CV (l2), CV (l1)]
ELSE NWD[CV (l1), CV (l2)]
END)