Kihagyás

Többrelációs lekérdezések

Jellemzően több táblát érintenek a lekérdezések

  • Több reláció is felsorakoztatható a FROM záradékban
  • Kétértelműséget a <reláció>.<attribútum> szintaxissal lehet feloldani

Formális szemantika

  • Vegyük a FROM záradékban szereplő relációk Descartes-szorzatát
  • Alkalmazzuk a WHERE záradék feltételét
  • Vetítsünk a SELECT záradék oszlopaira

Többrelációs példa

SELECT sör
FROM Szeret, Látogat
WHERE kocsma = 'Joe bárja'
    AND Látogat.alkesz = Szeret.alkesz;

Operációs szemantika

  • A FROM záradékbili táblá(k)hoz egy sorváltozó tartozik
    • A sorok minden lehetséges kombinációját vesszük
    • Ha a változók a WHERE feltételének eleget tesznek, akkor azt továbbküldjük a SELECT záradéknak

Explicit sorváltozók

  • Egy relációhoz tartozó "sorváltozót" át lehet nevezni
    • Hasznos, amikor egy táblának több példányára is szükség van
      • Elkerülve a kétértelműséget
    • Akkor is alkalmazható, ha egyébként nem szükséges
      • Például hosszú nevű tábláknál, vagy allekérdezéseknél

Önmagával vett kapcsolás

SELECT b1.név, b2.név
FROM Sörök b1, Sörök b2
WHERE b1.gyártó = b2.gyártó
    AND b1.név < b2.név;

Gyakori módszer, hogy ne legyen a párosításokban ismétlődés

Alkérdések

"subqueries"

A FROM és WHERE záradékokban zárójelezett SELECT _ FROM _ WHERE alkérdéseket is használhatunk, speciális esetben a SELECT-ben is használható.

Alkérdések zárójelben vannak, így azokat nem választjuk el sorelválasztóval...

Alkérdések - Példa

Keressük meg Joe bárját látogató vendégek kedvelt söreit

SELECT sör
FROM Szeret , (SELECT alkesz
    FROM Látogat
    WHERE kocsma = 'Joe bárja') JD
WHERE Szeret.alkesz = JS.alkesz;

Az alkérdés itt megadja a keresett alkeszeket, majd azzal tudunk összehasonlítani a Szeret-el

Egy soros alkérdések

  • Ha egy alkérdés biztosan egy sort ad eredményül, akkor konstans értékként használható
    • Általában egy oszlopa ban
    • Ha több eredménye lenne, azt futásidejű hibát okoz
    • Érdemes olyan függvényt alkalmazni, aminek egy soros tulajdonsága ismert
      • MAX, MIN, FIRST, COUNT, AVG ...

Egysoros alkérdés - Példa

Keressük meg azokat a kocsmákat, ahol a miller ugyanannyiva kerül, mint Joe bárjában a Bud

SELECT kocsma
FROM Felszolgál
WHERE sör = 'Miller'
    AND ár = (SELECT ár
        FROM Felszolgál
        WHERE kocsma = 'Joe bárja'
           AND sör = 'Bud');

Kotlin reminder

Most kérdezhetnénk, hogy honnan tudjuk mi azt, hogy csak egy elemmel tér vissza ez az alkérdés.

Jusson eszünkbe, hogy a Felszolgál(kocsma, sör, ár) esetén a kocsma és sör párban kulcsot alkotnak, ami azt jelenti, hogy azért, mert a kulcsra szűrtünk, az előfordulás garantáltan egyedi.

Az így kapott egy sor lesz a WHERE-ben felhasznált konstans.

Tartalmazás - IN

  • WHERE záradékban használható
  • <sor> IN (<alkérdés>) feltétel akkor és csak akkor igaz, ha a sor eleme az alkérdés eredményének
    • Elentétnek adott a <sor> NOT IN (<alkérdés>) feltétel

Tartalmazás - Példa

Listázzuk ki azon sörök minden információját, amiket Fred kedvel

SELECT *
FROM Sörök
WHERE név IN (SELECT sör
    FROM Szeret
    WHERE alkesz = 'Fred');

Tartalmazás vs Descartes-szorzat

SELECT a
FROM R, S  -- Dupla ciklus R és S felett 
--> Tehát veszünk minden R x S párosítást
WHERE R.b = S.b;  -- És abból vesszük az egyezőket
SELECT a
FROM R  -- Egy ciklus R sorai felett
WHERE b IN (SELECT b FROM S); -- S-et csak egyszer vesszük

A Descartes-szorzat a legtöbb rendszerben engedi az ismétlődést (for performance reasons), így annak elkerülésére tartalmazást szoktunk ellenőrizni

Létezés - EXISTS

  • EXISTS (<alkérdés>) akkor és csak akkor igaz, ha az alkérdés eredménye nem üres
    • Legalább egy sort visszaad
    • Hasonlóan NOT EXISTS (<alkérdés>) is létezik

Létezés - Példa

keressünk olyan söröket, amiknek a gyártói nem gyártanak más sört

SELECT név
FROM Sörök b1
WHERE NOT EXISTS (
    SELECT *
    FROM Sörök
    WHERE gyártó = b1.gyártó
        AND név <> b1.név
);

<> is \(\ne\) in SQL

Bármelyik - ANY

  • x \(\circ\) ANY (<alkérdés>) akkor és csak akkor igaz, ha az alkérdés legalább egy sorával igaz a \(\circ \in \{=,<,\ldots\}\) feltétel
    • Példa: x > ANY (<alkérdés>)
  • Az alkérdés sorai egy mezőből kell álljanak

Mindegyik - ALL

  • x \(\circ\) ALL (<alkérdés>) akkor és csak akkor lesz igaz, ha az alkérdés minden sorát kielégíti a \(\circ\in\{=,>,\ldots\}\) feltétel

Halmazműveletek

  • (<alkérdés>) UNION (<alkérdés>)
  • (<alkérdés>) INTERSECT (<alkérdés>)
  • (<alkérdés>) MINUS (<alkérdés>)
    • EXCEPT megyezzik a MINUS-al

Halmazműveletek - Motiváció

  • Projekciónál hatékonyabb nem kiszűrni az ismétlődéseket
  • A metszet és különbség számításakor általában egy rendezés előbb megtörténik
    • Ezt követően az ismétlődések szűrése kissebb számítási igényű

Ismétlődés módosítása

  • SELECT DISTINCT _
    • Ismétlődések kiszűrése
  • SELECT ALL _, UNION ALL _ ...
    • Ismétlődések megtartása

Kapcsolások - JOIN

  • Számos formája van SQL-ben
  • Állhat önmagában, vagy a FROM záradékban használható

Kapcsolási formák

Természetes kapcsolás

R NATURAL JOIN S;

Szorzat

R CROSS JOIN S;

Theta kapcsolás

R JOIN S ON F;
Alkesz JOIN Látogat
   ON név = alkesz;

Relációs algebra és SQL - Példák

\[ \large{\sigma_{A=\text{'a3'}\,\land\,B>2}(R)} \]
SELECT * FROM R WHERE A = 'a3' AND B > 2;

\[ \large{\Pi_A(\sigma_{A=\text{'a1'}})(R)} \]
SELECT A FROM R WHERE A = 'a1';

\[ \large{R\cup S} \]
(SELECT * FROM R) UNION (SELECT * FROM S);

\[ \large{R\cap S} \]
(SELECT * FROM R) INTERSECT (SELECT * FROM S);

\[ \large{R-S} \]
(SELECT * FROM R) EXCEPT (SELECT * FROM S);

\[ \large{R\times S} \]
SELECT * FROM R, S;
--vagy
SELECT * FROM R CROSS JOIN S;

\[ \large{R\Join S} \]
SELECT * FROM R NATURAL JOIN S;

\[ \large{R\Join_{R.B=S.B} S} \]
SELECT * FROM R JOIN S
    ON R.B = S.B;
SELECT * FROM R INNER JOIN S
    ON R.B = S.B;
SELECT * FROM R, S
    WHERE R.B = S.B;

\(\large{\sigma_{R.B=S.B}(R\times S)}\)


Létezik relációs kalkulus, amik deklaratív nyelvek (nem részletezi a köztes lépéseket)

Sor,- és oszlopkalkulus