Posted By: Jovo () on 'CZdatabases'
Title:     Jovo 3
Date:      Sat Oct 21 12:27:20 2000

Z Jovova zapisniku - 3:"Setreni prace (1)"
==========================================

  Narazil jsem na paradni trik. Situace : mame par projektu a 
na nich pracuji lidi :

TABLE lidi               TABLE projekt1 TABLE projekt2 TABLE projekt3
                                                                               
   
id        jmeno   trida  id             id   status     id    hodin   
=======================  ======         =============   ===========  
(serial) (char10) (int)  (int)          (int) (char1)   (int) (int)   
-----------------------  ------         -------------   -----------   
1         Pepa     15    1              3      "A"      3     15      
2         Venca    10    2              2      "+"                 
3         Jiricek  15                   5      "N"                 
4         Pavla    45
5         Lida     18


(pro puristy: vase namitka, ze by se projekt1,2,3 dal zdrcnout do
 jedne tabulky, kde by bylo navic cislo projektu, je spravna. Zde 
 jde o modelovy pripad - id z "lidi" se dovazi i jinam a tabulky 
 nemaji stejne sloupce.)

Ukol, zpracovat vsechny lidi, kteri maji nejakou tridu (my zvolime 
trida>5, aby se vybrali vsichni) a pracuji na nejakem projektu. 

  Select *
    from lidi
        where
                trida vyhovuje podmince
          AND   nekde pracuji

Reseni je nekolik:

1]  vic selectu za sebou 
        SELECT  *
          FROM  lidi, projekt1
          WHERE trida>5
            AND lidi.id = projekt1.id;
        zpracuj_dotaz ....;
        SELECT  *
          FROM  lidi, projekt2
          WHERE trida>5
            AND lidi.id = projekt2.id;
        zpracuj_dotaz ....;
        SELECT  *
          FROM  lidi, projekt3
          WHERE trida>5
            AND lidi.id = projekt3.id;
        zpracuj_dotaz ....;

2]  select budeme konstruovat. 
      Tento postup se hodi, kdyz mame tabulky a sloupce v nejake pekne
    relaci (napr. zde vazba projekt?<->lidi jde pres id, a jmena 
    tabulek se lisi jen cislem

      funkce vrat_retez(int num) {
        RETURN "SELECT  * FROM lidi,projekt" + num + 
                "WHERE trida>5 AND lidi.id = projekt" + num
      };
      
      LET dotaz = vrat_retez(1);  spust_dotaz;zpracuj_dotaz ....;
      LET dotaz = vrat_retez(2);  spust_dotaz;zpracuj_dotaz ....;
      LET dotaz = vrat_retez(3);  spust_dotaz;zpracuj_dotaz ....;
    nebo
        FOR n=1 TO 2 DO 
                LET dotaz = vrat_retez(n);  spust_dotaz;zpracuj_dotaz ....;
        END

        - pozn.: Pokud by se tabulky jmenovaly jinak, musi se pozmenit i 
          funkce vrat_retez :-)
        
3]  "oblibeny" union
        SELECT  *
          FROM  lidi, projekt1
          WHERE trida>5
            AND id IN (
                        SELECT  id
                          FROM  projekt1
                        UNION
                        SELECT  id
                          FROM  projekt2
                        UNION
                        SELECT  id
                          FROM  projekt3
                      );
       zpracuj_dotaz ....;

        - prednosti :
                - UNION automaticky vyhazuje duplicity (zde id 2 a 3)
                - jenom jeden select 
        - vady :
                - SELECT je slozeny
                - kdyz je to nad vic tabulkami a vazba jde pres vicero
                  sloupcu, tak uz to neni tak prehledne a spatne se to ladi
                - UNION automaticky vyhazuje duplicity :-) nekdy potrebujeme
                  i duplicitni zaznamy (ne zrovna v tomto pripade).


  Takze pokud bych mel neco doporucit pak (3), potom (2) a kdyby to 
nefungovalo, tak (1). 
  Videl jsem lidi, kteri zacali od (1) a prepsali ho do zpusobu (3). Nevim jak
vy, ale me kdyz to funguje, tak se snazim do toho moc nevrtat a vam doporucuji
v opravnenych pripadech totez :-)

Vas Jovo.

Search the boards