Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Rekurzivni upit u tabeli koja referencira na samu sebe

[es] :: Baze podataka :: Rekurzivni upit u tabeli koja referencira na samu sebe

[ Pregleda: 6548 | Odgovora: 19 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

Shadowed
Vojvodina

Član broj: 649
Poruke: 12846



+4783 Profil

icon Rekurzivni upit u tabeli koja referencira na samu sebe12.01.2008. u 12:04 - pre 197 meseci
Naslov nije bas najbolji, ali nemam pojma kako bih preciznije naveo, ako neko ima predlog, menjam :)

Elem, o cemu se radi. Imam tabelu koja ima ID, neke podatke i krajnju kolonu ParentID koja sadrzi vrednost ID-a iz iste tabele (samo nekog drugog reda). Mislim da ce jasnije biti ako se pogleda slika. Levo je ono sto je predstavljeno podacima u bazi, desno je gore tabela a dole rezultat upita za recimo zadat broj 4. Ono sto mi je potrebno (ako je to ikako moguce) je da jednim upitom dobijem red sa trazenim ID-om, njegov parent, parent-ov parent i tako sve do root-a (kojem je ParentID null ili neka predvidjena vrednost). Mogao bih to uraditi tako sto pozovem prvo jedan upit da dobijem red pa onda jedan za parent-a i tako do root-a, ali bih vise voleo ako se to moze dobiti jednim upitom.
Nije u pitanju neka konkretna baza, jer ce mi trebati za vise njih (tako da bi navodjenje razlika u resenju za konkretne baze bilo pozeljno). Doduse, verovatno ce biti u pitanju najcesce MS SQL, zatim Access i MySql.
Evo i slike:


Hvala unapred :)
Prikačeni fajlovi
 
Odgovor na temu

goranvuc
Goran Vucicevic
Novi Sad

Član broj: 4934
Poruke: 1846
*.dialup.neobee.net.



+41 Profil

icon Re: Rekurzivni upit u tabeli koja referencira na samu sebe12.01.2008. u 13:29 - pre 197 meseci
Ono sto odmah mogu da ti kazem je da Access zaboravis, a u MSSQL-u to lako mozes postici sa rekurzivnom funkcijom.
 
Odgovor na temu

Shadowed
Vojvodina

Član broj: 649
Poruke: 12846



+4783 Profil

icon Re: Rekurzivni upit u tabeli koja referencira na samu sebe12.01.2008. u 18:43 - pre 197 meseci
Hm, nisam bas siguran da znam i kako, gledao sam malo primere koje sam izguglao, ali nisam ukapirao. Najgore sto nisam u mogucnosti da probam. Moze primer?

A i nesto razmisljam da cu aplikaciju ograniciti ipak samo na MS SQL... i iz nekih drugih razloga...
 
Odgovor na temu

goranvuc
Goran Vucicevic
Novi Sad

Član broj: 4934
Poruke: 1846
*.dialup.neobee.net.



+41 Profil

icon Re: Rekurzivni upit u tabeli koja referencira na samu sebe12.01.2008. u 19:12 - pre 197 meseci
Mislio sam na koriscenje UDF (User defined function) u MS SQL-u. Ja sam to koristio kada mi je trebala rekurzija u problematici sledivosti proizvodnje.

Druga varijanta koju sam koristio kada je stvar bila isuvise komplikovana za primenu je koristenje trigger-a za upis putanje (od top level parenta do konkretnog clana) u odgovarajuce polje (dakle mora se predvideti polje za putanju clana hijerarhije), sto mi je omogucilo vecu fleksibilnost u koristenju SQL-a za izvlacenje bilo kakvih setova: "daj svu decu koja su direktni ili indirektni potomci clana 5" i sl.

Inace, vec je bilo nesto na ovu temu, potrazicu pa ti javim.

Evo nadjoh nesto sto je skorije bilo http://www.elitesecurity.org/t253117
 
Odgovor na temu

Shadowed
Vojvodina

Član broj: 649
Poruke: 12846



+4783 Profil

icon Re: Rekurzivni upit u tabeli koja referencira na samu sebe12.01.2008. u 21:14 - pre 197 meseci
OK, ovo ce biti korisno. Ja se bas nadao da postoji neko resenje u cistom sql-u, nezavisno od RDBMS-a, ali nema veze. Na kraju krajeva, jos uvek ispitujem stvari, mozda ovo zaobidjem skroz :)

Zahvaljujem :)
 
Odgovor na temu

jablan

Član broj: 8286
Poruke: 4541



+710 Profil

icon Re: Rekurzivni upit u tabeli koja referencira na samu sebe12.01.2008. u 21:41 - pre 197 meseci
Citat:
goranvuc: upis putanje (od top level parenta do konkretnog clana) u odgovarajuce polje (dakle mora se predvideti polje za putanju clana hijerarhije), sto mi je omogucilo vecu fleksibilnost u koristenju SQL-a za izvlacenje bilo kakvih setova: "daj svu decu koja su direktni ili indirektni potomci clana 5" i sl.

I ja obično primenjujem ovo rešenje, samo korišćenjem stored procedure (ili aplikativne logike) umesto trigera. Sve parente ili svu decu dobijaš prostim "LIKE" uslovom.

Ustvari, primenjivao ranije, pošto u Railsu to ima gotovo:

http://wiki.rubyonrails.org/rails/pages/ActsAsTree

:P
 
Odgovor na temu

goranvuc
Goran Vucicevic
Novi Sad

Član broj: 4934
Poruke: 1846
*.dialup.neobee.net.



+41 Profil

icon Re: Rekurzivni upit u tabeli koja referencira na samu sebe12.01.2008. u 21:45 - pre 197 meseci
Trigere koristim za odrzavanje hijerarhije (prilikom premestanja nekog clana i vezivanje za nekog drugog parenta), a za manipulaciju naravno ne.
 
Odgovor na temu

BigFoot
Boban Jovanović
Arilje

Član broj: 1098
Poruke: 991
212.200.207.*



+35 Profil

icon Re: Rekurzivni upit u tabeli koja referencira na samu sebe13.01.2008. u 02:05 - pre 197 meseci
Ovo ti je klasičan problem zapisa strukture stabla u strukturu tipa tabele. Pored polja ParentID, koristi dodatno polje Level koje odredjuje nivo dubine stabla za svaki element i stvari će postati znatno jednostavnije.
Two beer or not two beer...
 
Odgovor na temu

dusans
Stojanov Dušan
Pančevo

Član broj: 9551
Poruke: 1343
195.252.70.*



+311 Profil

icon Re: Rekurzivni upit u tabeli koja referencira na samu sebe13.01.2008. u 11:40 - pre 197 meseci
Moze vrlo lako u bilo kom SQL-u ako smes da ogranicis broj nivoa (u praksi ces uvek imati nekav broj nivoa preko kog nema smisla ici, npr. suludo je da ce neko da rucno organizuje podatke na vise od 20-30 nivoa)

Primer za T-SQL i 5 nivoa (vise nivoa, veci upit):

Code:


SELECT Data.Name,
            Parent1.Name AS Parent1Name,
            Parent2.Name AS Parent2Name,
            Parent3.Name AS Parent3Name,
            Parent4.Name AS Parent4Name,
            Parent5.Name AS Parent5Name
FROM Data
LEFT OUTER JOIN Data AS Parent1 ON Data.ParentID = Parent1.ID
LEFT OUTER JOIN Data AS Parent2 ON Parent1.ParentID = Parent2.ID
LEFT OUTER JOIN Data AS Parent3 ON Parent2.ParentID = Parent3.ID
LEFT OUTER JOIN Data AS Parent4 ON Parent3.ParentID = Parent4.ID
LEFT OUTER JOIN Data AS Parent5 ON Parent4.ParentID = Parent5.ID



Pozdrav!
 
Odgovor na temu

goranvuc
Goran Vucicevic
Novi Sad

Član broj: 4934
Poruke: 1846
*.dialup.neobee.net.



+41 Profil

icon Re: Rekurzivni upit u tabeli koja referencira na samu sebe13.01.2008. u 11:56 - pre 197 meseci
Njemu trebaju podaci kao redovi, a ne svi preci u jednom redu. Ali OK, moze posluziti za dobijanje putanje.
 
Odgovor na temu

Shadowed
Vojvodina

Član broj: 649
Poruke: 12846



+4783 Profil

icon Re: Rekurzivni upit u tabeli koja referencira na samu sebe13.01.2008. u 21:32 - pre 197 meseci
Moglo bi posluziti za nevolju, ali je goran u pravu kada kaze za redove, posto mi jedan red kasnije postaje jedan objekat u programu.
 
Odgovor na temu

Sasa Popovic
Software Architect / co-owner, Vega IT
Sourcing
Novi Sad

Član broj: 7402
Poruke: 33
...vl-edge-dnevnik.neobee.net.

Sajt: www.vegaitsourcing.rs


Profil

icon Re: Rekurzivni upit u tabeli koja referencira na samu sebe14.01.2008. u 08:13 - pre 197 meseci
Pozdrav svima,

Ako koristite SQL Server 2005 (ili Express Edition) onda je resenje koriscenje rekurzivnih upita uz upotrebu Common Table Expressions. Vise o ovome mozete procitati na: http://msdn2.microsoft.com/en-us/library/ms186243.aspx.

Napisao sam kratak primer koji demonstrira ono sto je trazeno u post-u:
Code:

declare @data table  (ID int not null, [Name] nvarchar(10) not null, ParentID int null)

insert into @data values (0, 'root', null)
insert into @data values (1, 'ch1', 0)
insert into @data values (2, 'ch2', 0)
insert into @data values (3, 'ch3', 0)
insert into @data values (4, 'ch1-1', 1)
insert into @data values (5, 'ch1-2', 1);

WITH SelectedData (ID, [Name], ParentID, Level)
AS
(
    SELECT ID, [Name], ParentID, 0 AS Level
    FROM @data
    WHERE ID = 4

    UNION ALL

    SELECT parent.ID, parent.[Name], parent.ParentID, Level + 1
    FROM  @data parent
        INNER JOIN SelectedData child on child.ParentID = parent.ID

)
SELECT ID, [Name], ParentID
FROM SelectedData
ORDER BY Level DESC


Pozdrav,
Sasa
 
Odgovor na temu

hyle
Perica Milošević
Belgrade

Član broj: 30030
Poruke: 150
77.247.200.*

Sajt: www.linkedin.com/in/peric..


+4 Profil

icon Re: Rekurzivni upit u tabeli koja referencira na samu sebe14.01.2008. u 08:28 - pre 197 meseci
Možda bi ti ovo bilo zanimljivo: The Nested Set Model
 
Odgovor na temu

vilyu
Web Developer
Beograd, Srbija

Član broj: 1188
Poruke: 444



+2 Profil

icon Re: Rekurzivni upit u tabeli koja referencira na samu sebe14.01.2008. u 09:17 - pre 197 meseci
Citat:
dusans: Moze vrlo lako u bilo kom SQL-u ako smes da ogranicis broj nivoa (u praksi ces uvek imati nekav broj nivoa preko kog nema smisla ici, npr. suludo je da ce neko da rucno organizuje podatke na vise od 20-30 nivoa)

Moram da primetim da je ovo resenje izuzetno neprakticno, usled velikog broja spajanja tabela koje ce trajati znatno duze nego vise pretrazivanja jedne tabele u slucaju rekurzivnog algoritma.
Pera električar 0637129710, BG, preporučujem.
 
Odgovor na temu

Shadowed
Vojvodina

Član broj: 649
Poruke: 12846



+4783 Profil

icon Re: Rekurzivni upit u tabeli koja referencira na samu sebe14.01.2008. u 23:07 - pre 197 meseci
E, hvala ljudi, iskreno receno, nisam se ni nadao ovolikom odzivu :)
 
Odgovor na temu

RAIN--SONG

Član broj: 6674
Poruke: 148
193.198.27.*



Profil

icon Re: Rekurzivni upit u tabeli koja referencira na samu sebe21.01.2008. u 16:58 - pre 197 meseci
Sada ne znam jesam dobro razumio pitanje, ali koliko kuzim trebas napraviti neku hijerarhiju. Netko je dao link na model ugnijezdjenoga skupa (nested sed model), a ja cu ovdje objasniti kako se stablo pravi pomocu popisa modela susjedstva (eng. . Adjacency list model). Tj. opisat cu samo kreiranje stabla pomocu popisa modela susjedstva. Imas ovo jako dobro objasnjeno u knjizi Joe Celko's Sql for Smarties, a ima i knjiga samo o stablima. Kako ovdje nije dopusten piratluk ne mogu je staviti. PM-aj za dodatne informacije o knjizi ako hoces.

Dakle imamo neko stablo recimo ovo http://en.wikipedia.org/wiki/Image:Binary_tree.svg


dijete otac
=============
'2' NULL
'7' '2'
'5' '2'
'2' '7'
'6' '7'
'5' '6'
'11' '6'
'9' '5'
'4' '9'

Opsirnije ovdje http://en.wikipedia.org/wiki/Adjacency_list

Ovo se moze napisat pomocu matrice susjedstva, ali meni se ne da tipkat. =)

Dakle pravljenje tablice

CREATE TABLE Stablo_susjedstva
(child CHAR(2) NOT NULL,
parent CHAR(2), -- null is korijen
PRIMARY KEY (child, parent));

Kod je iz gore navedene knjige ili mu ja barem slican =)

Ogranicenja su da ima samo jedan korijen.
CREATE TABLE
(child CHAR(2) NOT NULL,
parent CHAR(2), -- null is root
PRIMARY KEY (child, parent),
CONSTRAINT jedan_korijen
CHECK((SELECT COUNT(*)
FROM AdjTree
WHERE parent IS NULL) = 1)
...);

nema kruzenja etc...

Obilasci bi islo ovako:

SELECT P1.child, ' je roditelj ', C1.child
FROM Stablo_susjedstva AS P1, Stablo_susjedstva AS C1
WHERE P1.child = C1.parent;


etc... etc...

Uglavnom ona knjiga je ono sto ti treba ako nisam u krivu. =)








 
Odgovor na temu

Fitopatolog
Dušan Marjanov
Novi Sad

Član broj: 90936
Poruke: 683
212.200.214.*



+3 Profil

icon Re: Rekurzivni upit u tabeli koja referencira na samu sebe21.01.2008. u 18:02 - pre 197 meseci
Ne čitate ostale teme na ovom forumu?

rešenje već imate u temi "Zadatak za ER SQL znalce". Treba koristiti rekurzivni SQL i opciju "WITH" u DB2 i MSSQL bazama i opciju "CONNECT BY" u Oraklu.
 
Odgovor na temu

Sasa Popovic
Software Architect / co-owner, Vega IT
Sourcing
Novi Sad

Član broj: 7402
Poruke: 33
...vl-edge-dnevnik.neobee.net.

Sajt: www.vegaitsourcing.rs


Profil

icon Re: Rekurzivni upit u tabeli koja referencira na samu sebe21.01.2008. u 18:29 - pre 197 meseci
@RAIN--SONG, ne bih se bas slozio da je resenje koje ste naveli ono sto je trazeno. Kako bi ste sa tim resenjem izvukli sve strukturu za child sa ID-jem 4? U svakom slucaju, resenje je koriscenje Common Table Expressions kao sto sam naveo ranije.

@Fitopatolog, ja nisam procitao tu temu do sada a sada kada sam je procitao ne bih rekao da smo mi ostali ovde pogresili time sto smo probali da pomognemo autoru pitanja. Ako nekome ko nije koristio Common Table Expressions (ili slicne metode) napisete da je resenje koriscenje Common Table Expressions i date mu link na neki primer koji nema veze sa onim sto on trazi onda u vecini slucajeva za onog ko je postavio pitanje odgovor nema mnogo smisla.
 
Odgovor na temu

PavleBgd
Pavle Joksimovic
Beograd

Član broj: 25177
Poruke: 112
*.154.eunet.yu.



Profil

icon Re: Rekurzivni upit u tabeli koja referencira na samu sebe26.01.2008. u 18:02 - pre 196 meseci
Zasto ne probas sa kursorima da resis problem rekurzivnog ispisa strukture?

Code:

CREATE PROCEDURE [ReferenceTableTest] 
    @IDParent INT
AS

DECLARE @IDTempID INT

set nocount on
IF EXISTS (SELECT * FROM tempdb.dbo.sysobjects WHERE NAME = '##TestStruktura')    
DROP TABLE ##TestStruktura
CREATE TABLE [dbo].[##TestStruktura] (
    [IDChild] [int] NULL ,
    [Opis] [varchar] (50)  NULL ,
    [IDParent] [int] NULL
) ON [PRIMARY]

DELETE FROM ##TestStruktura
INSERT INTO ##TestStruktura
SELECT * FROM TestTabela
WHERE IDChild=@IDParent

DECLARE cur_lss CURSOR
FOR SELECT IDChild FROM ##TestStruktura
OPEN cur_lss
FETCH cur_lss INTO @IDTempID
WHILE (@@FETCH_STATUS <> -1)
BEGIN
    IF (@@FETCH_STATUS <> -2)
    BEGIN
        INSERT INTO ##TestStruktura
        SELECT * FROM TestTabela
        WHERE IDParent=@IDTempID
    END        
    FETCH cur_lss INTO @IDTempID
END
close cur_lss
DEALLOCATE cur_lss
set nocount off
select * from ##TestStruktura

DROP TABLE ##TestStruktura
GO


TestTabela treba da bude iste strukture kao tabela ##TestStruktura.
Output se generise dinamicki, nema ogranicenja po pitanju dubine strukture.
Iako sam na slican rekurzivno mogao da resim ovaj problem
ovo resenje mi se jos tada ucinilo jednostavnijim i elegantnijim
Pozdrav

[Ovu poruku je menjao PavleBgd dana 27.01.2008. u 08:41 GMT+1]
 
Odgovor na temu

vokus
Vojčo Kraljevski
Makedonija

Član broj: 30597
Poruke: 36
62.162.216.*



Profil

icon Re: Rekurzivni upit u tabeli koja referencira na samu sebe27.01.2008. u 20:25 - pre 196 meseci
Ako Oracle dolazi u obzir onda vidi ovo:
http://www.psoug.org/reference/connectby.html
Vojčo
 
Odgovor na temu

[es] :: Baze podataka :: Rekurzivni upit u tabeli koja referencira na samu sebe

[ Pregleda: 6548 | Odgovora: 19 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.