13.2.2017

SQL/Liitokset

Liitokset - haut useaan tauluun



SELECT AsiakasNimi, tilausnumero
FROM asiakas INNER JOIN tilaus
ON asiakas.asiakastunnus =
tilaus.asiakastunnus;


Perinteinen liitos



SELECT yritys.yrtun, Nimi,         -- Hae yrityksen tunnus, nimi
Sukunimi, Etunimi, Palkka -- ja henkilön nimi + palkka
FROM yritys, henkilo -- näistä tauluista
WHERE yritys.yrtun = henkilo.yrtun -- Liitosehto!
AND Palkka > 2500 -- Hakuehto palkalle
ORDER BY Nimi -- Lajittelu

Perinteinen liitos / 2


SELECT osasto.ostun, osnimi, snimi, enimi, kunta
FROM osasto, henkilo -- monta taulua -> liitos
WHERE osasto.ostun = henkilo.ostun -- liitosehto
AND kunta = 'TURKU'
ORDER BY osnimi

====> ====> ====> ====> ====> ====> ====> ====> ====>
Liitoksen seurauksena liitetään kaikki
liitosehdon mukaiset rivit:

Metsä, Mikko |TURKU | 1 <-----> |1|Tietohallinto
Ranta, Laura |TAMPERE | 1 <-----> |1|Tietohallinto
Virta, Jukka |TURKU | 3 <-----> |3|Tuotanto
Meri, Leo |TURKU | 3 <-----> |3|Tuotanto
Jokinen, Lyly|TAMPERE | 3 <-----> |3|Tuotanto
====> ====> ====> ====> ====> ====> ====> ====> ====>
Näistä hyväksytään vain turkulaiset, joten tuloksena:
+ ----- + ------------- + --------- + --------- +
| ostun | osnimi | snimi | enimi | kunta |
+ ----- + ------------- + --------- + --------- +
| 1 | Tietohallinto | Metsä | Mikko | TURKU |
| 3 | Tuotanto os. | Virta | Jukka | TURKU |
| 3 | Tuotanto os. | Meri | Leo | TURKU |
+ ----- + ------------- + ---------- + -------- +


Puuttuva liitosehto?


SELECT osasto.ostun, osnimi, snimi, enimi, kunta
FROM osasto, henkilo
WHERE kunta = 'TURKU'
ORDER BY osnimi

====> ====> ====> ====> ====> ====> ====> ===
+ ---------- + ----------- + ---------- + ---
| ostun | osnimi | snimi | enimi | kunta |
+ ---------- + ----------- + ---------- + ---
| 4 | Markkinointi | Metsä | Mikko | TURKU |
| 4 | Markkinointi | Virta | Jukka | TURKU |
| 4 | Markkinointi | Meri | Leo | TURKU |
| 2 | Talous toim. | Virta | Jukka | TURKU |
| 2 | Talous toim. | Meri | Leo | TURKU |
| 2 | Talous toim. | Metsä | Mikko | TURKU |
| 1 | Tietohallinto | Metsä | Mikko | TURKU |
| 1 | Tietohallinto | Virta | Jukka | TURKU |
| 1 | Tietohallinto | Meri | Leo | TURKU |
| 3 | Tuotanto os. | Meri | Leo | TURKU |
| 3 | Tuotanto os. | Metsä | Mikko | TURKU |
| 3 | Tuotanto os. | Virta | Jukka | TURKU |
+ ---------- + ----------- + ---------- + ---
12 rows

Taulujen viitenimi




SELECT os.ostun, os.osnimi, he.snimi, he.enimi, he.kunta
FROM osasto os , henkilo he
WHERE os.ostun = he.ostun
AND he.kunta = 'TURKU'
ORDER BY os.osnimi;
Käy usein myös AS-muodossa:

...
FROM osasto AS os, henkilo AS he
...

Uusi liitossyntaksi (suositellaan)



SELECT yritys.Yrtun, Nimi,      -- Hae yrityksen tunnus, nimi
Sukunimi, Etunimi, Palkka -- henkilön suku-/etunimi+palkka
FROM yritys -- YRITYS –taulusta, joka
INNER JOIN henkilo -- liitetään HENKILO-tauluun
ON yritys.Yrtun = henkilo.Yrtun -- Liitosehto
WHERE Palkka > 2500 -- Hakuehto palkalle
ORDER BY Nimi -- Lajittelu

Uusi liitossyntaksi / 2



SELECT os.ostun, os.osnimi, he.snimi,
he.enimi, he.kunta
FROM osasto AS os INNER JOIN henkilo AS he
ON os.ostun = he.ostun
WHERE he.kunta = 'TURKU'
ORDER BY os.osnimi;

Monen taulun liitos (Taululkm >=3)



SELECT he.htun, he.snimi, pr.pnimi, ph.tunnit
FROM henkilo AS he INNER JOIN proj_henk AS ph
ON he.htun = ph.htun
INNER JOIN projekti AS pr
ON pr.ptun = ph.ptun
ORDER BY ph.tunnit DESC;

Ulkoliitos (outer join)





SELECT AsiakasNimi, tilausnumero
FROM asiakas
LEFT OUTER JOIN tilaus
ON asiakas.asiakastunnus = tilaus.asiakastunnus;


Ulkoliitosesimerkki



Hae kaikki projektit henkilöineen ja henkilöiden tunnit projektia kohtia. Hae mukaan myös ne projektit, joissa ei ole vielä merkitty henkilöille tunteja (ei henkilöitä)

SELECT pr.ptun, pr.pnimi, ph.htun, ph.tunnit
FROM projekti AS pr LEFT OUTER JOIN
proj_henk AS ph
ON pr.ptun = ph.ptun
ORDER BY ph.tunnit DESC;
Järjestys oleellinen: vasemmalla olevasta taulusta halutaan kaikki rivit


Liitos itseensä



SELECT a.nimi
FROM asiakas a, asiakas b
WHERE a.emoyritystunnus = b.asiakastunnus
AND b.asiakastunnus = 'JAMK';


Liitos itseensä / Esimerkki



Kuvittele sama taulu itsensä kanssa vierekkäin ja tee niiden liitos

Hae ne käyttäjät, joilla on sama palkka kuin Jukka Virralla (htun=2134). Huom: Ei väliä mikä palkka Virralla on.

SELECT a.snimi, a.enimi, a.palkka
FROM henkilo AS a INNER JOIN henkilo AS b
ON a.palkka = b.palkka
AND b.htun = 2134;

Yhdiste (UNION)


Kaksi taulua (tai useampia) yhdistetään samantyyppisen tiedon avulla


Yhdiste (UNION)




Esim. opettajien ja opiskelijoiden puhelinnumerot:
SELECT OpeNimi AS Nimi, PuhNro, ’opettaja’
FROM opettaja
UNION
SELECT OpiskNimi, PuhNro, ’opiskelija’
FROM opiskelija
ORDER BY 1;

Yhdiste (UNION)



Akateeminen esimerkki: Hae ne käyttäjät, joilla on sama palkka kuin Jukka Virralla (htun=2134) tai Mikko Metsällä (htun=2234)
SELECT a.snimi, a.enimi, a.palkka
FROM henkilo AS a INNER JOIN henkilo AS b
ON a.palkka = b.palkka
AND b.htun = 2134
UNION
SELECT a.snimi, a.enimi, a.palkka
FROM henkilo AS a INNER JOIN henkilo AS b
ON a.palkka = b.palkka
AND b.htun = 2234;


Liitokset ja ryhmittely



Hae osastoittain osaston tunnus, nimi ja palkat yhteensä sekä palkkojen keskiarvo

SELECT os.ostun, os.osnimi, sum(he.palkka) AS summa,
CAST(AVG(he.palkka) AS DECIMAL(7,2)) AS keskiarvo
FROM osasto AS os LEFT OUTER JOIN henkilo AS he
ON os.ostun = he.ostun
GROUP BY os.ostun, os.osnimi