webForumDet fria alternativet

rekursiv select på en hierarkisk tabell

Databaser & SQL

3 svar · 311 visningar · startad av sgtpepper

Medlem sedan apr. 20007 588 inlägg
Frågan#1

Jag har lite problem med att få till en bra SQL-sats för följande tabeller:

NODES
------------
INTEGER  N_ID      The unique identifier for this node.
VARCHAR  N_NAME    The title of this node.

NODEBR
------------
INTEGER  N_ID      The identifier of the node. A foreign key from the NODES table.
INTEGER  NB_PARENT The identifier of the parent node that contains this node instance. A foreign key from the NODES table.

Tabellerna innehåller fler kolumner men det är dessa som är väsentliga. NODEBR representerar en instans av en nod i NODES i en hierarkisk struktur.

Det jag vill göra är att lista alla noder som har en specifik nod som anfader eller vad man skall kalla det, t.ex alla noder som är besläktade med nod med n_id = 61.

Det jag pillat med hittils ser ut så här:

WITH parent(nb_parent, nb_id, n_name) AS
(SELECT nb_parent, nb_id, n_name
	FROM nodebr nb, nodes n
	WHERE nb_parent = 61 AND nb.nb_id = n.n_id

UNION ALL

SELECT c.nb_parent, c.nb_id, p.n_name
	FROM nodebr c, nodes p
	WHERE p.n_id = c.nb_parent
)
SELECT DISTINCT nb_id, n_name FROM parent

Eftersom jag inte är världens bästa SQL-kille så fungerar det självklart inte som jag vill :) så jag behöver lite hjälp.

Jag kör DB2.

------------------
det finns ingen.info tillgänglig.

"inside every human being there's an american trying to get out".

[Redigerat av sgtpepper den 10 dec 2001]

Medlem sedan dec. 200012 464 inlägg
#2

With är ju inte så vanligt, jag har aldrig sett det i någon annan än db2. Så det här är helt otestat.

WITH parent(n_id, n_name) AS
(SELECT  n.n_id, n_name	
  FROM nodebr nb, nodes n	
 WHERE nb_parent = 61 
   AND nb.nb_id = n.n_id
 UNION all
 SELECT c.n_id, c.n_name	
   FROM parent p, nodes c, nodebr nb
  WHERE p.n_id = nb.nb_parent
    and nb.n_id = c.n_id )
 SELECT DISTINCT n_id, n_name FROM parent

------------------
essentitia preter non sans multiplicandum

Medlem sedan apr. 20007 588 inlägg
#3

Tack LarsG du är en klippa! :)

Jag skall testa SQL-satsen på jobbet i morgon, återkommer om jag har några frågor.

Eftersom WITH är ovanligt i andra RDBMSer, hur skulle man gjort annars, finns det något mer generiskt sätt att lösa det? När jag surfade runt lite så hittade jag en sida hos Oracle som visade en sats som gjorde det jag ville, men den använde Oracle-specifik syntax (minns inte exakt vad det var nu), går det att plocka ut alla besläktade noder i en hierarki med "vanlig" ANSI-SQL på något sätt?

------------------
det finns ingen.info tillgänglig.

"inside every human being there's an american trying to get out".

Medlem sedan dec. 200012 464 inlägg
#4

With-konstruktionen finns med i SQL-99 så det är ANSI.

Alternativet är väl att skriva en rekursiv procedur.

OT:
Konstruktionen i Oracle heter connect by. Det tråkiga med den är att den är begränsad till en tabell.

------------------
essentitia preter non sans multiplicandum

[Redigerat av LarsG den 10 dec 2001]

258 ms totalt · 4 externa anrop · v20260731065814-full.e96017d9
123 ms — deklarationer (db)
0 ms — hämta statistik (cache)
128 ms — hämta tråd, inlägg och bilagor (db)
125 ms — ändringar (db)