SELECTy ze staré písemky

Základní kurs podávající průřez problematikou. Jsou popsány tři úrovně pohledu na data. Konceptuální modelování je založeno na ER modelu, databázové modelování se zabývá podrobně teorií relačního modelu dat (algebra, kalkul, základy SQL, algoritmy návrhu relační databáze, normální formy) a principy objektově-relačního modelu. Transakční zpracování a paralelní přístup, algoritmy implementace relačních operací.
Uživatelský avatar
Che
Donátor
Donátor
Příspěvky: 166
Registrován: 2. 6. 2005 12:29
Typ studia: Informatika Mgr.
Bydliště: EU
Kontaktovat uživatele:

SELECTy ze staré písemky

Příspěvek od Che »

Ahoj,
zkusil jsem vyřešit příklady na SELECT z jedné staré písemky, na kterou se tady už odkazovalo a rád bych se podělil o svá řešení - samozřejmě s nadějí, že se najde někdo, kdo mně upozorní na chyby :wink:

a)

Kód: Vybrat vše

SELECT MAX (věk) FROM Student LEFT JOIN Zápis ON (Student.čSt = Zápis.čSt) WHERE Student.obor LIKE 'Informatika' OR Zápis.jmP IN (SELECT jmP FROM Učitel NATURAL JOIN Předmět WHERE jmUč LIKE 'XY') ;
b)

Kód: Vybrat vše

SELECT DISTINCT jmSt FROM Student NATURAL JOIN Zápis WHERE jmP IN (SELECT jmP FROM Předmět AS Předmět1 JOIN Předmět AS Předmět2 USING (čas) WHERE Předmět1.jmP <> Předmět2.jmP) ;
c)

Kód: Vybrat vše

SELECT jmUč FROM Učitel WHERE EXISTS (SELECT * FROM Zápis NATURAL JOIN Předmět WHERE Učitel.čUč = Předmět.čUč GROUP BY jmP HAVING COUNT(DISTINCT jmP) < 5) ;
d)
S tím stále bojuju... :roll:
shoot that shit
Uživatelský avatar
Che
Donátor
Donátor
Příspěvky: 166
Registrován: 2. 6. 2005 12:29
Typ studia: Informatika Mgr.
Bydliště: EU
Kontaktovat uživatele:

Příspěvek od Che »

Tak i ten poslední...

d)

Kód: Vybrat vše

SELECT jmSt FROM Student WHERE čSt IN (SELECT čSt FROM Student NATURAL JOIN Zápis GROUP BY čSt HAVING COUNT(jmP) >= ALL ( SELECT COUNT(jmP) FROM Zápis GROUP BY čSt) ) ;
Napadlo mně i jednodušší řešení, ale využivalo konstrukce COUNT(jmP) = MAX(COUNT(jmP)). Podle slajdů by to teoreticky mělo jít, ale nikde jsem se s něčím podobným nesetkal, tak nevím...
shoot that shit
Uživatelský avatar
Angel
Matfyz(ák|ačka) level III
Příspěvky: 121
Registrován: 9. 9. 2005 19:28
Typ studia: Informatika Mgr.
Bydliště: Znojmo / Praha
Kontaktovat uživatele:

Příspěvek od Angel »

Budu psat postupne, abys mohl jeste nejak reagovat (pokud jdes dnes na zkousku :)). Ja se prave ucim a mozna na ni pujdu - aspon to zkusit ;-).

ad a) je nutny ten prvni left join? Nestacil by pouze natural join? (nemam tucha co je silnejsi, jen se ptam)

ad b) to mas urcite spatne, protoze ten druhy select musi byt na dvojce (dvojic predmetu ve stejny cas muze byt vic a tvuj dotaz vraci pouze jeden predmet na radek, takze pak muze mit student zapsany dva predmety z tohoto seznamu, ale podminku nesplnuje...)
Na spravnym dotaz zatim delam :)

ad c) ten je asi dobre... ja napsal neco takovyhleho

Kód: Vybrat vše

SELECT jmUc FROM Ucitel NATURAL JOIN (SELECT cUc FROM Zapis NATURAL JOIN Predmet GROUP BY cUc HAVING count(*) < 5) AS t1
ad d) a tady sem prilis (skoro vubec) nepochopil zadani.
Naposledy upravil(a) Angel dne 6. 6. 2006 10:11, celkem upraveno 4 x.
gASK
Admin(ka) level I
Příspěvky: 635
Registrován: 9. 6. 2005 12:33
Typ studia: Informatika Mgr.
Bydliště: Konečně Vinohrady:)
Kontaktovat uživatele:

Příspěvek od gASK »

Angel píše:Budu psat postupne, abys mohl jeste nejak reagovat (pokud jdes dnes na zkousku :)). Ja se prave ucim a mozna na ni pujdu - aspon to zkusit ;-).

ad a) je nutny ten prvni left join? Nestacil by pouze natural join?
Je. Potřebuješ tam nechat i studenty, co nemaj nic zapsáno, neboť i oni můžou bejt na informatice.

Pokud by bylo řečeno, že každý student má alespoň jeden zápis, pak tam můžeš vrazit Natural Join.
Uživatelský avatar
Angel
Matfyz(ák|ačka) level III
Příspěvky: 121
Registrován: 9. 9. 2005 19:28
Typ studia: Informatika Mgr.
Bydliště: Znojmo / Praha
Kontaktovat uživatele:

Příspěvek od Angel »

aaa, i see
Uživatelský avatar
Angel
Matfyz(ák|ačka) level III
Příspěvky: 121
Registrován: 9. 9. 2005 19:28
Typ studia: Informatika Mgr.
Bydliště: Znojmo / Praha
Kontaktovat uživatele:

Příspěvek od Angel »

Jeste dotaz, LEFT JOIN je to stejne jako LEFT OUTER JOIN?
Ve slajdech ma o LEFT JOIN pouze zminku v souvislosti s OUTER ...
Uživatelský avatar
Angel
Matfyz(ák|ačka) level III
Příspěvky: 121
Registrován: 9. 9. 2005 19:28
Typ studia: Informatika Mgr.
Bydliště: Znojmo / Praha
Kontaktovat uživatele:

Příspěvek od Angel »

mno, sice je to prasacky, ale nevim, me nic jineho nenapadlo:

Kód: Vybrat vše

b)
SELECT jmSt FROM Student NATURAL JOIN (SELECT t1.cSt FROM (SELECT * FROM Zapis NATURAL JOIN Predmet) AS t1 INNER JOIN (SELECT * FROM Zapis NATURAL JOIN Predmet) AS t2 ON t1.cas = t2.cas AND t1.cSt = t2. cSt AND t1.jmP > t2.jmP) as t3
melo by to fungovat (zkousel jsem v mysql).
Uživatelský avatar
Che
Donátor
Donátor
Příspěvky: 166
Registrován: 2. 6. 2005 12:29
Typ studia: Informatika Mgr.
Bydliště: EU
Kontaktovat uživatele:

Příspěvek od Che »

Angel píše: Jeste dotaz, LEFT JOIN je to stejne jako LEFT OUTER JOIN?
Ve slajdech ma o LEFT JOIN pouze zminku v souvislosti s OUTER ...
Jo, je. To OUTER se běžně vynechává, takže jen LEFT | FULL | RIGHT JOIN...
Angel píše:Budu psat postupne, abys mohl jeste nejak reagovat (pokud jdes dnes na zkousku :)). Ja se prave ucim a mozna na ni pujdu - aspon to zkusit ;-).
Jo, taky to jdu dneska zkusit :)
Angel píše: ad a) je nutny ten prvni left join? Nestacil by pouze natural join? (nemam tucha co je silnejsi, jen se ptam)
Přesně tak, jak psal gASK.
Angel píše: ad b) to mas urcite spatne, protoze ten druhy select musi byt na dvojce (dvojic predmetu ve stejny cas muze byt vic a tvuj dotaz vraci pouze jeden predmet na radek, takze pak muze mit student zapsany dva predmety z tohoto seznamu, ale podminku nesplnuje...)
Na spravnym dotaz zatim delam :)
Jasně, když se na to teď dívám, tak jsem vyplodil dost pěknou blbost... :?

Zkoušel jsem to přepsat, ale byls rychlejší ;) Ale stejně už to tady postnu, zajímalo by mně, jestli se dá spojovat tabulky i takhle: SELECT * FROM (t1 JOIN t2) as tt1 JOIN (t3 JOIN t4) AS tt2 ? Podobně, jak to máš ty, ale bez toho aby ta spojení v závorkách byla přes poddotaz (tj. bez SELECTu).

b)

Kód: Vybrat vše

SELECT DISTINCT jmSt FROM Student WHERE EXISTS (SELECT * FROM (Zápis NATURAL JOIN Předmět) AS PřZ1 INNER JOIN (Zápis NATURAL JOIN Předmět) AS PřZ2 ON (PřZ1.čas = PřZ2.čas AND PřZ1.jmP <> PřZ2.jmP AND PřZ1.čSt = PřZ2.čSt) WHERE Student.čSt = PřZ1.čSt);
shoot that shit
Uživatelský avatar
Angel
Matfyz(ák|ačka) level III
Příspěvky: 121
Registrován: 9. 9. 2005 19:28
Typ studia: Informatika Mgr.
Bydliště: Znojmo / Praha
Kontaktovat uživatele:

Příspěvek od Angel »

Che píše: Zkoušel jsem to přepsat, ale byls rychlejší ;) Ale stejně už to tady postnu, zajímalo by mně, jestli se dá spojovat tabulky i takhle: SELECT * FROM (t1 JOIN t2) as tt1 JOIN (t3 JOIN t4) AS tt2 ? Podobně, jak to máš ty, ale bez toho aby ta spojení v závorkách byla přes poddotaz (tj. bez SELECTu).
Podle me to tak nejde (teda aspon ne v mysql, kde sem si ty sql dotazy zkousel). Taky sem to tam prvne psal bez toho select ale nepustilo me to.
Ale jak je to podle normy nevim. Na ten tvuj dotaz to vyhodi nejakou strasne dlouho chybu :).

Jeste jdu na tu druhou pisemku, tak to sem taky hodim (a jestli mas ty, tak muzes taky).
gASK
Admin(ka) level I
Příspěvky: 635
Registrován: 9. 6. 2005 12:33
Typ studia: Informatika Mgr.
Bydliště: Konečně Vinohrady:)
Kontaktovat uživatele:

Příspěvek od gASK »

Sorry, blbě jsem to přečetl. Tak zapomeňte co jsem tu psal.



Já jsem se těm podselektům vyhnul úplně:

Kód: Vybrat vše

SELECT DISTINCT a1.jmSt FROM ( ( ( Predmet NATURAL JOIN Zapis ) NATURAL JOIN Student ) AS a1 ) INNER JOIN ( ( ( Predmet NATURAL JOIN Zapis ) NATURAL JOIN Student ) AS a2 ) ON a1.jmP < a2.jmP AND a1.cas = a2.cas AND a1.jmSt = a2.jmSt
Uživatelský avatar
Angel
Matfyz(ák|ačka) level III
Příspěvky: 121
Registrován: 9. 9. 2005 19:28
Typ studia: Informatika Mgr.
Bydliště: Znojmo / Praha
Kontaktovat uživatele:

jina pisemka

Příspěvek od Angel »

Zkusim postupne reseni teto pisemky. (sry ze jsem si trochu upravil velikosti pismen ze zadani).
a)

Kód: Vybrat vše

SELECT mzda, Zam.c_zam, max(dolet) FROM Zam NATURAL JOIN Smi NATURAL JOIN Aero WHERE Zam.c_zam IN (SELECT Zam.c_zam FROM Zam NATURAL JOIN Smi GROUP BY c_zam HAVING count(*) > 3) GROUP BY Zam.c_zam
b)

Kód: Vybrat vše

SELECT jm_zam FROM Zam WHERE mzda < ANY (SELECT MIN(cena) FROM Let WHERE z = 'pha' AND do = 'hon')
gASK
Admin(ka) level I
Příspěvky: 635
Registrován: 9. 6. 2005 12:33
Typ studia: Informatika Mgr.
Bydliště: Konečně Vinohrady:)
Kontaktovat uživatele:

Re: jina pisemka

Příspěvek od gASK »

Angel píše: b)

Kód: Vybrat vše

SELECT jm_zam FROM Zam WHERE mzda < ANY (SELECT MIN(cena) FROM Let WHERE z = 'pha' AND do = 'hon')
Tady musíš místo Zam dát ( Zam NATURAL JOIN Smi GROUP BY c_zam ) - abys měl jenom piloty. Ti, co nesmí na žádné letadlo (tedy nemaj pilotní oprávnění) jsou ne-piloti a hodí se v další podotázce.
Uživatelský avatar
Angel
Matfyz(ák|ačka) level III
Příspěvky: 121
Registrován: 9. 9. 2005 19:28
Typ studia: Informatika Mgr.
Bydliště: Znojmo / Praha
Kontaktovat uživatele:

Příspěvek od Angel »

jj, mas pravdu, nejak sem si jeste u b neuvedomil, ze existuji ne-piloti, na co jsem prisel az u c :-). Ale to group tam asi nebude ne? Jen distinct... :?:
gASK
Admin(ka) level I
Příspěvky: 635
Registrován: 9. 6. 2005 12:33
Typ studia: Informatika Mgr.
Bydliště: Konečně Vinohrady:)
Kontaktovat uživatele:

Příspěvek od gASK »

Angel píše:jj, mas pravdu, nejak sem si jeste u b neuvedomil, ze existuji ne-piloti, na co jsem prisel az u c :-). Ale to group tam asi nebude ne? Jen distinct... :?:
Group nebo distinct - výsledek je stejný. Jde o to, co se ti víc "líbí". Pokud bys tam napsal GROUP BY, můžeš tu podmínku z WHERE navíc hodit do HAVING. Ale funkčně to bude ekvivalentní, jde jen o "styl" :twisted:
Uživatelský avatar
Angel
Matfyz(ák|ačka) level III
Příspěvky: 121
Registrován: 9. 9. 2005 19:28
Typ studia: Informatika Mgr.
Bydliště: Znojmo / Praha
Kontaktovat uživatele:

Příspěvek od Angel »

Hmm hmm :-). Mozna se to do tech dvou naucim :). Akorat tohle je zatim jen prvni cast, z er a transakci zatim nic neumim. A taky sem zvedavej, jak tam napisu nejakej sql bez pristupu k interpretu :-/.
c)

Kód: Vybrat vše

SELECT jm_zam, mzda FROM Zam WHERE c_zam NOT IN (SELECT Zam.c_zam FROM Zam NATURAL JOIN Smi) AND mzda > ANY (SELECT avg(mzda) FROM (SELECT DISTINCT mzda FROM Zam NATURAL JOIN Smi) AS t1)
Odpovědět

Zpět na „DBI025 Databázové systémy“