7. fejezet - Feladatok

A következőekben a relációs világban példaként jól ismert Vállalat sémára vonatkozóan látunk néhány feladatot (összevetve az SQL megoldással):

  1. Feladat: Számoljuk meg az alkalmazottakat!

    Megoldás:

    SQL: select count(*) from emp;
    XQuery: count(//Emp)
  2. Feladat: Keressük meg az 1000-nél többet kereső alkalmazottakat!

    Megoldás:

    SQL: select * from emp where sal > 1000;
    XQuery: //Emp[Sal>1000]
  3. Feladat: Keressük meg az 1000-nél többet, de 200-nél kevessebet kereső alkalmazottakat!

    Megoldás:

    SQL: select * from emp where sal between 1000 and 2000;
    XQuery: //Emp[Sal>1000][Sal<2000]
    
    (: nincs between függvény XQuery esetám, írjunk egyet :)
    declare function local:between($value as xs:decimal, $min as xs:decimal, $max as xs:decimal) as xs:boolean 
    { 
    	$value >= $min and $value <= $max 
    };
    (: the modified solution :)
    //Emp[local:between(Sal,1000,2000)] 
  4. Feladat: Kerresük meg azokat akik nem kaptak jutalékot.

    Megoldás:

    SQL: select * from emp where comm is null;
    XQuery: //Emp[empty(Comm/text())]

    Megjegyzés

    pusztán csak a //Emp[empty(Comm)] kifejezést használva rossz eredményt kaphatnánk, ami nem elfogadható, mert az empty(Comm) függvény akkor is igazal tér vissza, ha az elem maga hiányzik.

  5. Feladat: Az első 5 alkalmazott kiírása.

    Megoldás:

    SQL: select * from emp limit 5;
    XQuery: //Emp[position() <=5]
  6. Feladat: Számoljuk ki az éves keresétét az alkalmazottaknak, ami nem más mint a 12 havi kereset plusz a jutalék. Miután a jutalék null is lehet ezt helyettesíteni kell.

    Megoldás:

    SQL: select 12 * sal + ifnull(comm,0) from emp;
    XQuery: //Emp/(12*number(Sal)+(if(exists(Comm/text())) then number($Comm) else 0))
  7. Feladat: Az alkalmazott neve mellett jelenjen meg a keresete:

    Megoldás:

    SQL: select ename, 12 * sal + ifnull(comm,0) as "Annual Salary" from emp; 
    XQuery: 
    for $emp in //Emp 
    return <Emp> {$emp/Ename} <AnnualSalary> 
    	{12*number($emp/Sal)+ 
    	(if (exists($emp/Comm/text())) then number($emp/Comm) 
    		else 0)
    	 }
     </AnnualSalary>
    </Emp>
  8. Feladat: Listázzuk ki azon alkalmazottakat, akik nevében szerepel az "AR" .

    Megoldás:

    SQL: select * from emp where ename like "%AR%"
    XQuery://Emp[contains(Ename,"AR")] 
  9. Feladat: Kerresük annak a részlegnek a nevét ahol 'SMITH' dolgozik!

    Megoldás:

    SQL: select dept.dname from emp, dept where dept.deptno = emp.deptno and ename='SMITH';
    XQuery: let $dept := //Emp[Ename='SMITH']/DeptNo return //Dept[DeptNo = $dept ]/Dname 
    XPath:  //Dept[DeptNo = //Emp[Ename='SMITH']/DeptNo]/Dname
  10. Feladat: Listázzuk ki az összes részeleget és az ott dolgozók számát.

    Megoldás:

    SQL: select dname, count(*) from dept natural join emp group by emp.deptno;
    XQuery: 
    for $dept in //Dept let $headCount := count(//Emp[DeptNo=$dept/DeptNo]) 
    return <Dept>
     {$dept/Dname}
     <HeadCount>{$headCount}</HeadCount>
     </Dept>
  11. Feladat: Listázzuk ki a dolgozók neve mellett a menedzserük nevét is.

    Megoldás:

    SQL: select e.ename, m.ename from emp e, emp m where e.mgr = m.empno;
    XQuery: 
    for $emp in //Emp 
    	let $manager := //Emp[EmpNo = $emp/MgrNo] return <Emp> 
    	{$emp/Ename} <Manager>{string($manager/Ename)}</Manager>
     </Emp>
  12. Feladat: A menedzserek esetén írassuk ki az átlag, min és max keresetet.

    Megoldás:

    SQL: select count(*), round(avg(sal)), min(sal), max(sal) FROM emp WHERE job='MANAGER';
    XQuery:
    let $managers := //Emp[Job='MANAGER'] return <Statistics> <Count>{(count($managers}</Count> <Average>{round(avg($managers/Sal))}</Average> <Min>{min($managers/Sal)}</Min> <Max>{max($managers/Sal))}</Max>
     </Statistics> 
  13. Feladat: Írassuk ki beosztásonként az alkalmazottak számáz, álag és min, max keresetet ott ahol legalább két dolgozó van.

    Megoldás:

    SQL: select job, count(*), round(avg(sal)), min(sal), max(sal) FROM emp GROUP BY job HAVING count(*) > 1;
    XQuery: 
    for $job in distinct-values(//Emp/Job) 
    let $employees := //Emp[Job=$job]
     where count($employees) > 1
     return <Statistics>
     	<Job>{$job}</Job>
     	<Count>{count($employees )}</Count> <Average>{round(avg($employees /Sal))}</Average> <Min>{min($employees /Sal)}</Min>
    	 <Max>{max($employees /Sal)}</Max>
     </Statistics> 
  14. Feladat: Részlegenként írassuk ki az ott dolgozók nevét és keresetét, illetve az össz-keresetüket.

    Megoldás:

    SQL: This must generate a nested table.
    XQuery: 
    <Report> {
     for $dept in //Dept
     let $subtotal := sum(//Emp[DeptNo = $dept/DeptNo]/Sal) 
     return
      <Department> 
       {$dept/Dname}
       {for $emp in //Emp[DeptNo = $dept/DeptNo] 
        return <Emp> {$emp/Ename} {$emp/Sal} </Emp> 
        }
        <SubTotal>{$subtotal}</SubTotal>
      </Department> }
      <Total>{sum(//Emp/Sal)}</Total>
     </Report>