SQL-standardsättet att implementera rekursiva frågor, som implementerat t.ex. av IBM DB2 och SQL Server, är WITH
klausul. Se den här artikeln för ett exempel på att översätta en CONNECT BY
till en WITH
(tekniskt sett en rekursiv CTE ) -- exemplet är för DB2 men jag tror att det kommer att fungera på SQL Server också.
Edit:uppenbarligen kräver den ursprungliga queranten ett specifikt exempel, här är ett från IBM-webbplatsen vars URL jag redan har angett. Med tanke på en tabell:
CREATE TABLE emp(empid INTEGER NOT NULL PRIMARY KEY,
name VARCHAR(10),
salary DECIMAL(9, 2),
mgrid INTEGER);
där mgrid
refererar till en anställds chefs empid
, uppgiften är att hämta namnen på alla som rapporterar direkt eller indirekt till Joan
. I Oracle är det en enkel CONNECT
:
SELECT name
FROM emp
START WITH name = 'Joan'
CONNECT BY PRIOR empid = mgrid
I SQL Server, IBM DB2 eller PostgreSQL 8.4 (liksom i SQL-standarden, för vad det är värt;-), är den perfekt likvärdiga lösningen istället en rekursiv fråga (mer komplex syntax, men faktiskt ännu mer kraft och flexibilitet ):
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
Oracles START WITH
satsen blir den första kapslade SELECT
, basfallet för rekursionen, att vara UNION
ed med den rekursiva delen som bara är en annan SELECT
.
SQL Servers specifika smak av WITH
finns givetvis dokumenterat på MSDN, vilket också ger riktlinjer och begränsningar för att använda detta nyckelord, samt flera exempel.