/ Forside / Teknologi / Udvikling / SQL / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
SQL
#NavnPoint
pmbruun 1704
niller 962
fehaar 730
Interkril.. 701
ellebye 510
pawel 510
rpje 405
pete 350
gibson 320
10  smorch 260
Rekursivt query på træ
Fra : Leif Neland


Dato : 15-01-09 10:21

Jeg har et traditionelt træ, hvor hver node har et Id og et ParentId

Kan man lave et query, der giver alle undernoderne fra en node og nedad?

Er der et begrænset antal niveauer, kan jeg jo lave
select id from tabel
where id =123
union
select id from tabel
where parentid =123
union
select a.id from tabel a
inner join tabel b on a.parentid=b.id where b.parentid =123
union
select a.id from tabel a
inner join tabel b on a.parentid=b.id
inner join tabel c on b.parentid=c.id
where c.parentid =123
union
select a.id from tabel a
inner join tabel b on a.parentid=b.id
inner join tabel c on b.parentid=c.id
inner join tabel d on c.parentid=d.id
where d.parentid =123

Det må jeg så kunne proppe ind i en stored procedure.



 
 
Andreas Plesner Jaco~ (15-01-2009)
Kommentar
Fra : Andreas Plesner Jaco~


Dato : 15-01-09 10:31

On 2009-01-15, Leif Neland <leif@neland.dk> wrote:

> Jeg har et traditionelt træ, hvor hver node har et Id og et ParentId
>
> Kan man lave et query, der giver alle undernoderne fra en node og nedad?

På Oracle kan du bruge CONNECT BY:
http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/queries003.htm#i2060615

--
Andreas

Stig Johansen (15-01-2009)
Kommentar
Fra : Stig Johansen


Dato : 15-01-09 12:23

Leif Neland wrote:

> Jeg har et traditionelt træ, hvor hver node har et Id og et ParentId

Ja, det er den traditionelle problemstilling med styklistenedbrydning.

> Kan man lave et query, der giver alle undernoderne fra en node og nedad?

Ja.

> Er der et begrænset antal niveauer

Du bestemer selv grænsen, dog synes jeg at kunne huske, at MS Access har en
begrænsning på 28 niveauer.

> union

Brug UNION ALL, så du får 'duplicates' med.

> select id from tabel
> where parentid =123
> union

Jeg tror jeg har skrevet det før, men brug lige så mange LEFT OUTER JOINS
som du mener du har brug for af niveauer.

--
Med venlig hilsen
Stig Johansen

Leif Neland (17-01-2009)
Kommentar
Fra : Leif Neland


Dato : 17-01-09 02:50

Stig Johansen skrev:
> Leif Neland wrote:
>
>> Jeg har et traditionelt træ, hvor hver node har et Id og et ParentId
>
> Ja, det er den traditionelle problemstilling med styklistenedbrydning.
>
>> Kan man lave et query, der giver alle undernoderne fra en node og nedad?
>
> Ja.
>
>> Er der et begrænset antal niveauer
>
> Du bestemer selv grænsen, dog synes jeg at kunne huske, at MS Access har en
> begrænsning på 28 niveauer.
>

Jeg glemte vist at skrive det er MS Sqlserver v8

Hvordan får jeg lavet noget, der kan bruges i et query?

Select id,navn from træ where id in noder_under(123)

Kan man i øvrigt have tabelnavn som parameter?
Det antages af alle i forskellige tabeller har felterne id og parentid
Så man laver en generisk funktion noder_under(node,tabel)

Leif

Stig Johansen (17-01-2009)
Kommentar
Fra : Stig Johansen


Dato : 17-01-09 05:51

Leif Neland wrote:

> Jeg glemte vist at skrive det er MS Sqlserver v8
>
> Hvordan får jeg lavet noget, der kan bruges i et query?

Det ser ud til den understøtter rekursive UDF's.
Det her eksempel qmå være et godt udgangspunkt for forsøg:
<http://weblogs.sqlteam.com/jeffs/archive/2003/11/21/588.aspx>

> Kan man i øvrigt have tabelnavn som parameter?
> Det antages af alle i forskellige tabeller har felterne id og parentid
> Så man laver en generisk funktion noder_under(node,tabel)

Det plejer at blive noget 'hø' (for mig), fordi så skal man bygge SQL'et som
en streng, og EXEC'e det.

EXEC'en bliver udført i en anden context, og jeg har aldrig fået det til at
hænge sammen (bortset fra at bruge temporære tabeller).

--
Med venlig hilsen
Stig Johansen

Leif Neland (27-01-2009)
Kommentar
Fra : Leif Neland


Dato : 27-01-09 12:49

Stig Johansen skrev:
> Leif Neland wrote:
>
>> Jeg har et traditionelt træ, hvor hver node har et Id og et ParentId
>
> Ja, det er den traditionelle problemstilling med styklistenedbrydning.
>
>> Kan man lave et query, der giver alle undernoderne fra en node og nedad?
>
> Ja.
>
>> Er der et begrænset antal niveauer
>
> Du bestemer selv grænsen, dog synes jeg at kunne huske, at MS Access har en
> begrænsning på 28 niveauer.
>
>> union
>
> Brug UNION ALL, så du får 'duplicates' med.
>
>> select id from tabel
>> where parentid =123
>> union
>
> Jeg tror jeg har skrevet det før, men brug lige så mange LEFT OUTER JOINS
> som du mener du har brug for af niveauer.
>
Ja, det har du.

"SELECT m.link AS mlink, m1.link AS m1link, m2.link AS m2link ...
FROM menu m
LEFT JOIN menu m1 ON m1.parentid = m.id
LEFT JOIN menu m2 ON m2.parentid = m1.id
..... osv..
WHERE m.parentid=0
ORDER BY m,m1,m2..
"

Det kunne give en række "1,10,37,null,null,null"

Så har jeg brugt coalesce(m4.id,m3.id,m2.id,m1.id) as nodeid til at
finde id'et på den "yderste" node, 37 i dette tilfælde
Er der en smart funktion til at tælle antallet af (non-)nulls i et antal
felter, 3 i dette tilfælde, for at angive niveauet?
Andet end (pseudo)
if m7 is not null then 7 else
if m6 is not null then 6 else
if m5 is not null then 5 else
if m4 is not null then 4 else
if m3 is not null then 3 else
if m2 is not null then 2 else
if m1 is not null then 1 else 0 end if
end if
end if
end if
end if
end if
end if


smart_funktion(1,10,37,null,null,null)=3

Troels Arvin (15-01-2009)
Kommentar
Fra : Troels Arvin


Dato : 15-01-09 23:14

Leif Neland wrote:
> Jeg har et traditionelt træ, hvor hver node har et Id og et ParentId
[...]

"De tre store" databaser vil snart alle have understøttelse af rekursiv
SQL, via "common table expressions" (WITH RECURSIVE). DB2 og MSSQL har
allerede, mens Oracle først vil få det i næste opdatering til v. 11g[1];
Oracle har dog allerede længe haft en lidt mindre avanceret rekursions-
facilitet (CONNECT BY). PostgreSQL skulle også gerne snart få
understøttelse af standard rekursiv SQL.

Så: Hvis dit DBMS understøtter standard rekursiv SQL, synes det at være
vejen frem.

Hvis dit DBMS ikke understøtter det, er der alternative muligheder for at
modellere et hierarki. Nogle af disse vil antagelig også slå rekursiv SQL
performance-mæssigt, inden for visse brugs-scenarier. På http://
troels.arvin.dk/db/rdbms/links/#hierarchical har jeg samlet en række gode
links om emnet. Jeg kan anbefale at starte med Vadim Tropashkos oversigt
over mulighederne[2], som sammenfatter, hvornår hvilken model er på sin
plads.


Noter:
1: http://vadimtropashko.wordpress.com/2008/11/18/finally/
2: http://vadimtropashko.wordpress.com/2008/08/09/one-more-nested-
intervals-vs-adjacency-list-comparison/

Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408924
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste