| 
					
							
        
    
        
						
			 | 
			
			
					    
					
        
         
          
         
	
            | 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 |  
  |   |   |   
            
        
 
            
         
           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/
            
              |   |   
            
        
 
    
 
					
					 
			 | 
			
				
        
			 |