Tema: Re: SQL query klausimas
Autorius: Jornada Del Muerto
Data: 2011-03-02 12:24:49
Nedidelem db laisvai daryt galima 1 lenta manau:

objektas { id, parent_id, name, desc } 

kur parent id yra tevo id, po to traukt aliasindamas gali, pvz:


select 
    o1.id as o1_id, 
    o1.name as o1_name
-- vaikai 
    o2.id as o2_id,
    o2.name as o2_name
-- anukai
    o3.id as o3_id,
    o3.name as o3_name
from 
    objektas o1
left join objektas o2 on
    o2.parent_id = o1.id
left join objektas o3 on
    o3.parent_id = o2.id

    Cia aisku tik pavizdys kaip susijoinina lenta su pacia savimi, nezinau kokia programavimo kalba darysi, paprastai medinem strukturom kurios didelio ar neriboto dydzio gerai tinka:

    1. rekursija 
    2. lazy load -lazy load tai kada uzkrauni tik medzio pagrindinius elementus, o kada vartotojas atidarineja kazkuri uzkrauni jo vaikus ir t.t.. ta prasme is karto nekraunamas visas medis, o tik kada vartotojui to objekto vaiku prireikia, tai labai gerai tinka kada medis didelis ar net begalinis.

    Pvz tureciau as medzio controla, butu kazkas tokio:


// Isivaizduokime TreeNode father Tag memberis visada saugos node id
void FillTree (TreeNode father) {

    // nezinau kokiu budu dirbsi su db tai tik improvizuoju, kad daleiskime turime darbo su db biblioteka kuri turi tokia funkcija
    // paimame is db tik konkretaus elemento vaikus
    DataTable table = db.Query(
        "Select * From objektas Where prent_id = " + father.Tag.ToString());
    
    / ** tokiu budu neprireikia mums visam algoritmui jokios sudetingos SQL uzklausos **/


    // visus viakus pridedame prie medzio
    foreach(DataRow row in table.Rows){

        // sukuriamas vaiko medinis elementas
        TreeNode kid = new TreeNode(
            row["name"].ToString());

        // priskiriamas jam jo id
        kid.Tag = row["id"].ToString();

        // Kazkada vaikas irgi tampa tevu :)
        // krauname vaiko vaikus - kvieciame sia funkcija tik kad pildytu ji - kaip sakant darome rekursija
        FillTree (kid);

        // pridedamas vaikas prie medzio
        // rasyta is galvos, o su tree dirbau senokai tai cia gali paklaidu buti, svarbu kaip mazdaug veikt turi parodyt noriu
        // is esmes prisidejo vaikas ir jo visi vaikai ir vaiku vaikai ir t.t.. 
        // galima buvo pries kvieciant FillTree tapati daryti tada pirmiau ji pridetu o tik po to jo vaikus
        father.Nodes.Add(kid);
    }
}


O lazy load'ui labiau tinka OOP principas, isivaizduokime medzio elementas yra objektas:

class Node : TreeNode {
    
    // metoda kviesti geriausiai kaip kreipiamasi i tree elementa kad pakraut vaikus
    public vod LoadKids (){
        DataTable table = db.Query(
            "Select * From objektas Where prent_id = " + this.Tag.ToString());

        // visus viakus pridedame prie medzio
        foreach(DataRow row in table.Rows){

            // sukuriamas vaiko medinis elementas
            TreeNode kid = new TreeNode(
            row["name"].ToString());

            // priskiriamas jam jo id
            kid.Tag = row["id"].ToString();
            father.Nodes.Add(kid);
        }
    }
}


Na va siek tiek logikos pamastymams, kaip galima padaryti net neparasius jokios sudetingos SQL uzklausos, o trivialiai.

Sekmes!
JDM

"Deivas" <sd@dfds.lt> wrote in message news:op.vrn66yehf76c7y@merkys...
Dėkui labai visiems. Aš nei studentas nei ką, tiesiog prireikė čia tokį  
smulkų moduliuką parašyti, galvojau bus visai simple, bet va, susidūriau  
su tokiu galvosūkiu. Dar neturėjau laiko išbandyti pasiūlymų, bet manau,  
kad kas nors tiks.

Tiesa, prieš kelias dienas atėjo mintis, kad galbūt mano lentelės  
struktūra tokima reikalui netinkama. Gal reikia perdaryti kitaip. Čia  
kažkas, berods, panašų sprendimą minėjo. Aš galvoju, kad reikia daryti dvi  
lenteles.
Pirmoje - id, vardas, pavarde.
Antroje - id, tevo id, motinos id.

Tuomet gal būtų paprasčiau. Kurį variantą geriau pasirinkti. Duomenų nebus  
labai daug - na į metus koks 100 įrašų.
Dar kartą ačiū.


On Thu, 24 Feb 2011 21:41:54 +0200, Deivas <sd@dfds.lt> wrote:

> Sveiki,
>
> gal pagelbėsit. Tarkim turiu tokią lentelę:
>
> Id
> tevoId
> motinosId
> vardas
> pavarde
>
> Kaip parašyti užklausą, kad parodytų asmens tėvus ir senelius, t.y.:
>
> id, vardas, pavarde, TevoVardas, MotinosVardas, TevoTevoVardas,
> TevoMotinosVardas, MotinosTevoVardas, MotinosMotinosVardas
>
> Parašiau lakoniškai, bet tikiuosi esmę supratot. Ačiū iš anksto jeigu
> užvesit ant kelio.


-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/