Avatar billede gertnissen Nybegynder
17. august 2005 - 14:00 Der er 9 kommentarer og
1 løsning

child parent relation i samme tabel

Min tabel indeholder child parent relationer i mange niveauer.

f.eks. dette simple eksempel

child | parent
10    | 10
20    | 10
21    | 10
30    | 20
31    | 20
40    | 30
41    | 30
5    | 40
6    | 40
7    | 40
8    | 40
9    | 40
0    | 40
24    | 40
20    | 2
21    | 31
osv osv

Dvs. der kan være mange child's til hver parent og der kan være x niveauer mellem bund og top og dermed en skæv træ-struktur. (top værdien er altid kendt eller lig sig selv)

hvordan får jeg dem transponeret ud til (eller omvendt)

a|b|c|d|e|f|g|h
5|40|30|20|10
6|40|30|20|10
7|40|30|20|10
8|40|30|20|10
9|40|30|20|10
24|40|30|20|10
21|10
31|20|10
41|30|20|10
20|2

Ved kun at anvende SQL syntaks ?

Jeg har prøvet med en sub-select, idet jeg kender top parent (værdien 1). Men det giver ikke helt det ønskede resultat og ser lidt underlig ud.

select child, parent
from myData
where parent in (select child from myData where parent in
(select child from myData where parent in
  (select child from myData where parent in
  (select child from myData where parent = '5'))))

Hvordan løses dette ved kun at anvende SQL syntaks ?

På forhånd tak !
Avatar billede arne_v Ekspert
18. august 2005 - 15:48 #1
så vidt jeg ved er det kun Oracles SQL syntax som på fornuftig vis
kan håndtere et vilkårligt antal parent-child relationer
Avatar billede arne_v Ekspert
18. august 2005 - 15:50 #2
mit standard råd er at oprette en support tabel, men jeg tror faktisk ikke engang
at den kan løse dit problem

dit ønskede output er fundamentalt ikke-relationelt

så jeg tror at du bliver nødt til at læse op fra database i en data struktur
og så hente data ud fra den
Avatar billede gertnissen Nybegynder
18. august 2005 - 19:36 #3
Hej arne_v

Hvordan ville denne Oracle SQL syntaks se ud ?
Avatar billede arne_v Ekspert
18. august 2005 - 21:12 #4
jeg er ikke så stor en Oracle guru men anyway

CREATE TABLE tree (
    id INTEGER,
    name VARCHAR2(50),
    parent INTEGER,
    PRIMARY KEY (id)
);
INSERT INTO tree VALUES (0, 'root', NULL);
INSERT INTO tree VALUES (1, 'A', 0);
INSERT INTO tree VALUES (2, 'B', 0);
INSERT INTO tree VALUES (3, 'AA', 1);
INSERT INTO tree VALUES (4, 'AB', 1);
INSERT INTO tree VALUES (5, 'BA', 2);
INSERT INTO tree VALUES (6, 'BB', 2);
INSERT INTO tree VALUES (7, 'AAA', 3);
INSERT INTO tree VALUES (8, 'AAAA', 7);
SELECT t1.id c,t2.id p FROM tree t1,tree t2 WHERE t2.id IN (SELECT id FROM tree START WITH id = t1.parent CONNECT BY PRIOR parent = id) ORDER BY c,p DESC;

giver

        C          P
--------- ----------
        1          0
        2          0
        3          1
        3          0
        4          1
        4          0
        5          2
        5          0
        6          2
        6          0
        7          3
        7          1
        7          0
        8          7
        8          3
        8          1
        8          0

som jeg håber du kan se ligner noget - det er dog kun i 2 søjler men dit variabel
antal kolonner output er SQL'sk og ovenstående query resultat kunne nemt
formateres af et program til at se ud som det du ønsker
Avatar billede gertnissen Nybegynder
18. august 2005 - 21:22 #5
Tak for det, jeg må se om jeg kan finde en Oracle eller anden DB der understøtter START WITH id = t1.parent CONNECT BY PRIOR parent = id - måske kan det anvendes i DB2 ?

Som du skriver kan outputtet nu nemmere transponeres til mit absolut ikke-relationelle output.

Tak for hjælpen.
Avatar billede gertnissen Nybegynder
18. august 2005 - 21:23 #6
Hov, jeg mangler et [svar] fra dig - smider du lige et, så vi kan lukke spørgsmålet.
Avatar billede arne_v Ekspert
18. august 2005 - 21:28 #7
svar
Avatar billede arne_v Ekspert
18. august 2005 - 21:29 #8
jeg er ret sikker på at DB2 ikke har connect by
Avatar billede arne_v Ekspert
18. august 2005 - 21:29 #9
men ovenstående må kunne laves i enhver database med en hjælpe tabel
Avatar billede kjulius Novice
19. august 2005 - 20:57 #10
Jeg er godt klar over, at sagen er gammel, men jeg syntes alligevel den så så spændende ud, at jeg ikke ku' dy mig. Efter et par forsøg kom jeg frem til følgende enkle sætning:

select pc1.parent as a, pc1.child as b, pc2.child as c,
      pc3.child as d, pc4.child as e, pc5.child as f,
      pc6.child as g, pc7.child as h
from parentchild pc1
left join parentchild pc2 on pc1.child=pc2.parent
                          and pc2.parent<>pc2.child
left join parentchild pc3 on pc2.child=pc3.parent
                          and pc3.parent<>pc3.child
left join parentchild pc4 on pc3.child=pc4.parent
                          and pc4.parent<>pc4.child
left join parentchild pc5 on pc4.child=pc5.parent
                          and pc5.parent<>pc5.child
left join parentchild pc6 on pc5.child=pc6.parent
                          and pc6.parent<>pc6.child
left join parentchild pc7 on pc6.child=pc7.parent
                          and pc7.parent<>pc7.child
where pc1.parent=5

Hvis jeg ellers har forstået spørgsmålet (hvilket på ingen måde ikke er givet! ;-) skulle den løse opgaven. Men!, den returnerer to records (hvilket jeg, i min naivitet også må tilstå, at jeg synes dine testdata lægger op til). Hvis det er forkert, så vil jeg (hvis du stadig har interesse i problemet, naturligvis - ingen tvang her) gerne høre en forklaring på hvorfor det er forkert.
Jeg er godt klar over, at en sådan løsning ikke er optimal, da man er nødt til at definere en max. dybde. Til gengæld vil den kunne bruges i alle databaser. Endnu en gang forudsat at resultatet er rigtigt, naturligvis.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester