Zopar typov zlozitejsich prikladov pre SQL.

  1. Vypiste pre kazdeho zamestanca jeho sefa. Treba spravit spojenie 2 "instanci" tej istej tabulky, je vhodne si ich nejak dobre oznacit, nech sa nedopletiete pri pisani podmienok a vysledkov
    riesenie:
    SELECT p.ename, b.ename FROM emp p LEFT OUTER JOIN emp b ON p.mgr = b.empno;
    p oznacuje podriadeneho, b - sefa (boss).
  2. Vypiste pre kazdeho zamestnanca pocet jeho priamych podriadenych. Klasika, treba pouzit vhodny OUTER JOIN
    riesenie:
    SELECT b.ename, COUNT(p.empno) FROM emp p RIGHT OUTER JOIN emp b ON p.mgr = b.empno GROUP BY b.ename;
  3. Pre kazde oddelenie vypisat pocet analytikov. Pozor trikove!
    riesenie:
    Prve riesenie ktore nas napadne nieje uplne ono
    SELECT dept.dname, COUNT(emp.empno) FROM dept LEFT OUTER JOIN emp ON dept.deptno = emp.deptno WHERE emp.job = 'ANALYST' GROUP BY dept.dname;
    Najpriamejsie riesenie je pridat (napr. cez UNION) k tomu tie oddelenia, ktora sme zatial "nezaratali", ale nieje to elegatne a je to trochu reduntantne
    Problem s 1. pokusom je, ze sice sme cez outer join sice pridali vsetky oddelenia, ale cez podmienku sme ich hned ostranili. Elegantne riesenie je dat tu podmienku priamo do joinu
    SELECT dept.dname, COUNT(emp.empno) FROM dept LEFT OUTER JOIN emp ON dept.deptno = emp.deptno AND emp.job = 'ANALYST' GROUP BY dept.dname;
  4. Najst zamestanca s najvyssim platom.
    riesenie:
    SELECT ename FROM emp WHERE sal = (SELECT MAX(sal) FROM emp);
  5. Zobraz vsetky oddelenia, ktore maju VSETKYCH zamestnancov s platom viac ako 1000. (aj datalog) Klasika zmenit "pre vsetky" na "not existuje"
    SELECT dname FROM dept d WHERE NOT EXISTS (SELECT * FROM emp e WHERE e.sal < 1000 AND e.deptno = d.deptno)
    lacne_odd(D):-emp(_,_,_,_,_,S,_,DN), dept(DN,D,_),S<1000.
    drahe_odd(D):-dept(_,D,_),\+lacne_odd(D).
  6. Priklady na skuske predpokladam, ze budu najma takehoto druhu, asi o nieco komplikovanejsie (zlozitejsie podmienky, nutne joiny cez viac tabuliek atd.). Ale kombinaciou tychto postupov by to malo stacit.
  7. Odporucam pri pouzivani atributov tabuliek (v SELECT a WHERE klauze) tam vzdy pisat aj meno tabulky (prip. aliasu), aby ste sa vyhli zbytocnym chybam.

    Specificke pre datalog

  8. Datalog nema agregacne funkcie, ale niektore sa daju odsimulovat (konkretne viem o MIN, MAX, napr. MAX = prvok, od ktoreho neexistuje vacsii).
  9. Pre datalog su speficicke ulohy, ktore vyuzivaju jeho rekurzivnu podstatu (da sa aj v SQL, ale obtiazne, vid. prednaska).
  10. Vypiste vsetkych, ktory su vo firemnej hierarchi (pocet nadriadenych nad sebou) tak vysoko ako smith.
    riesenie:
    rovnaka_uroven(E1, E2) :- emp(E1, _, _, S1, _, _, _, _), emp(E2, _, _, S2, _, _, _, _), S1 = null, S2 = null.
    rovnaka_uroven(E1, E2) :- emp(E1, _, _, S1, _, _, _, _), emp(E2, _, _, S2, _, _, _, _), \+(S1 = null),\+(S2 = null), rovnaka_uroven(S1, S2).

    rovnako_vysoko_smith(N) :- emp(E1, N, _, _, _, _, _, _), emp(E2, smith, _, _, _, _, _, _), rovnaka_uroven(E1, E2).