Standardowy sposób implementacji zapytań rekurencyjnych w SQL, zaimplementowany m.in. przez IBM DB2 i SQL Server, to WITH
klauzula. Zobacz ten artykuł, aby zobaczyć jeden przykład tłumaczenia CONNECT BY
w WITH
(technicznie rekurencyjne CTE ) -- przykład dotyczy DB2, ale wierzę, że będzie działać również na serwerze SQL.
Edycja:najwyraźniej oryginalny querant wymaga konkretnego przykładu, oto jeden z serwisu IBM, którego adres URL już podałem. Biorąc pod uwagę tabelę:
CREATE TABLE emp(empid INTEGER NOT NULL PRIMARY KEY,
name VARCHAR(10),
salary DECIMAL(9, 2),
mgrid INTEGER);
gdzie mgrid
odwołuje się do empid
pracownika zadaniem jest zdobycie nazwisk wszystkich osób, które bezpośrednio lub pośrednio podlegają Joan
. W Oracle jest to proste CONNECT
:
SELECT name
FROM emp
START WITH name = 'Joan'
CONNECT BY PRIOR empid = mgrid
W SQL Server, IBM DB2 czy PostgreSQL 8.4 (a także w standardzie SQL, bo to jest warte;-) idealnym równoważnym rozwiązaniem jest zamiast tego zapytanie rekurencyjne (bardziej złożona składnia, ale w rzeczywistości jeszcze większa moc i elastyczność ):
WITH n(empid, name) AS
(SELECT empid, name
FROM emp
WHERE name = 'Joan'
UNION ALL
SELECT nplus1.empid, nplus1.name
FROM emp as nplus1, n
WHERE n.empid = nplus1.mgrid)
SELECT name FROM n
Oracle START WITH
klauzula staje się pierwszym zagnieżdżonym SELECT
, podstawowym przypadkiem rekurencji, ma być UNION
ed z częścią rekurencyjną, która jest po prostu kolejnym SELECT
.
Specyficzny smak WITH
SQL Server jest oczywiście udokumentowana w witrynie MSDN, która zawiera również wskazówki i ograniczenia dotyczące używania tego słowa kluczowego, a także kilka przykładów.