4.1 Yleistä SQL:stä 4.2 SQL-lauseet 4.3 DML: datan hallinta 4.4 DDL: rakenteen määrittäminen 4.5 DCL: valtuuttaminen 4.6 TxCL: tapahtumanhallinta

Samankaltaiset tiedostot
SQL - STRUCTURED QUERY LANGUAGE

SELECT-lauseen perusmuoto

SQL-perusteet, SELECT-, INSERT-, CREATE-lauseet

TIEDONHALLINTA - SYKSY Luento 10. Hannu Markkanen /10/12 Helsinki Metropolia University of Applied Sciences

HELIA 1 (14) Outi Virkki Tiedonhallinta

TIEDONHALLINTA - SYKSY Luento 8. Saapumisryhmä: Pasi Ranne /9/13 Helsinki Metropolia University of Applied Sciences

HELIA TIKO-05 1 (22) ICT03D Tieto ja tiedon varastointi E.Räty, O.Virkki

Kyselyn yleisrakenne:

Hakukyselyt: SELECT * FROM taulu WHERE sarake1 = Malli Nimi [WHERE sarake1 LIKE M% ] [WHERE BETWEEN ehto1 AND ehto2] [WHERE sarake1 IN/= (alikysely)]

Harjoitustehtävä 1. Harjoitustehtävä 2. Harjoitustehtävä 2. Harjoitustehtävä 2. Harjoitustehtävä 2. SQL kysely

SQL. ! nykystandardi SQL3 eli SQL'99. ! CREATE TABLE, ALTER TABLE ja DROP TABLE. ! CREATE VIEW ja DROP VIEW. ! CREATE INDEX ja DROP INDEX

Insert lauseella on kaksi muotoa: insert into taulu [(sarakenimet)] values (arvot)

TIEDONHALLINTA - SYKSY Luento 11. Hannu Markkanen /10/12 Helsinki Metropolia University of Applied Sciences

CSE-A1200 Tietokannat

FROM-lausekkeessa voidaan määritellä useampi kuin yksi taulu, josta tietoja haetaan: Tuloksena on taululistassa lueteltujen taulujen rivien

Helsingin yliopisto/tktl Tietokantojen perusteet, s 2007 SQL:n perusteet. Harri Laine 1. SQL tietokantakieli. SQL tietokantakieli

Opettajana Mika Sorsa, HAMK:n ammatillisen opettajakoulutuksen opetusharjoittelija

Tietokantojen perusteet k2004helsingin yliopisto/tktl Tietokantojen perusteet, s 2005 SQL-perusteet. Harri Laine 1. SQL tietokantakieli

määritellä ja muokata tietokantaa ja sen käyttöoikeuksia virittää tietokannan talletusrakenteita hakea tietoa tietokannasta

Liitokset - haut useaan tauluun

select tulostietomäärittely from taulukkeet [where valintaehdot] [group by ryhmitystekijät] [having ryhmärajoitteet] [order by järjestysperusta]

määritellä ja muokata tietokantaa ja sen käyttöoikeuksia virittää tietokannan talletusrakenteita hakea tietoa tietokannasta

Tietokantojen perusteet, syksy 1999 SQL- osa Harri Laine 1. SQL-valintaehto. SQL-valintaehto. Opettajien nimet: Opiskelijoiden pääaineet

CSE-A1200 Tietokannat

Relaation tyhjyyden testaaminen

Helsingin yliopisto, TKTL Tietokantojen perusteet, k 2000 SQL- osa Harri Laine 1. SQL-valintaehto. SQL-valintaehto.

Tällä viikolla. Kotitehtävien läpikäynti Aloitetaan Pelifirman tietovaraston suunnittelu Jatketaan SQL-harjoituksia

2. Haet työntekijöiden tiedot etunimen mukaan nousevasti järjestettyinä. (ORDER BY) SELECT * FROM employees ORDER BY firstname ASC;

SQL-kielen perusteet. Tietokantojen perusteet

Kyselyt: Lähtökohtana joukko lukuja Laskukaava kertoo miten luvuista lasketaan tulos soveltamalla laskentaoperaatioita

Koostefunktiot. Viisi standardifunktiota: Esim. montako henkilöä on henkilo-taulussa:

Harjoitustehtävä 1. Harjoitustehtävän 1 ratkaisu. Harjoitustehtävä 1. Relaatioalgebra -liitokset (join) Liitos

3. Taulujen määrittely ja muuttaminen

Relaatioalgebra. Kyselyt:

3. TAULUJEN MÄÄRITTELY JA MUUTTAMINEN

HELIA TIKO-05 1 (17) ICT03D Tieto ja tiedon varastointi Räty, Virkki

Relaatioalgebra. Relaatioalgebra. Relaatioalgebra. Relaatioalgebra - erotus (set difference) Kyselyt:

HAAGA-HELIA Heti-09 1 (12) ICT05 Tiedonhallinta ja Tietokannat O.Virkki Näkymät

Kirjoita jokaiseen erilliseen vastauspaperiin kurssin nimi, tenttipäivä, oma nimesi (selkeästi), opiskelijanumerosi ja nimikirjoituksesi

TIEDONHALLINNAN PERUSTEET - SYKSY 2013

Helsingin yliopisto, tktl DO Tietokantojen perusteet, kevät 2000 SQL- osa Harri Laine 1. SQL-yhteenvetofunktiot. SQL-yhteenvetofunktiot

Helsingin yliopisto, tktl DO Tietokantojen perusteet, kevät 2000 SQL- osa Harri Laine 1. SQL-yhteenvetofunktiot. SQL-yhteenvetofunktiot

Tietokantojen perusteet, syksy 1999 SQL- osa Harri Laine 1. SQL-yhteenvetofunktiot. SQL-yhteenvetofunktiot

HAAGA-HELIA TIKO-05 1 (19) ICT23a Tietokannan suunnittelu ja toteutus O.Virkki

HELIA 1 (14) Outi Virkki Tiedonhallinta

CSE-A1200 Tietokannat

Helsingin yliopisto Tietojenkäsittelytieteen laitos (H.Laine) Tietokantojen perusteet. Liitteenä: Tiivistelmä SQL-syntaksista

HELIA TIKO-05 1 (15) ICT03D Tieto ja tiedon varastointi Räty, Virkki

Yleinen SQL. Yleinen SQL. SQL:n kehitys

HELIA 1 (15) Outi Virkki Tietokantasuunnittelu

Helsingin yliopisto, Tietojenkäsittelytieteen laitos Tietokantojen perusteet, , H.Laine

Kirjoita kuhunkin erilliseen vastauspaperiin kurssin nimi, tentin päiväys, oma nimesi, syntymäaikasi ja nimikirjoituksesi.

Tietokannanhoitaja DBA (Database Administrator) ja tietokannan hallinta

Alkuarvot ja tyyppimuunnokset (1/5) Alkuarvot ja tyyppimuunnokset (2/5) Alkuarvot ja tyyppimuunnokset (3/5)

Tietokantojen perusteet, s 1999 SQL- osa Harri Laine 1. SQL -ohjelmistojen markkinaosuuksia SQL. SQL - historiaa. SQL - standardointi

joukko operaatioita, joilla relaatioista voidaan muodostaa uusia relaatioita joukko opin perusoperaatiot yhdiste, erotus, ristitulo, leikkaus

SQL:N PERUSTEET MARKKU SUNI

CS-A1150 Tietokannat CS-A1150 Tietokannat / 43

Helsingin yliopisto/tktl Kyselykielet, s 2006 Relaatiokalkyylit. Harri Laine 1

HELIA 1 (12) Outi Virkki Tiedonhallinta

Helsingin yliopisto/ tktl DO Tietokantojen perusteet, s 2000 Relaatioalgebra Harri Laine 1. Relaatioalgebra

Tiedonhallinnan perusteet. H11 Ovien ja kulun valvontajärjestelmän tietokanta

Relaatiomalli ja -tietokanta

Ohjelmistojen mallintamisen ja tietokantojen perusteiden yhteys

TIETOKANTOJEN PERUSTEET MARKKU SUNI

Tietokannat II -kurssin harjoitustyö

Tietokannat. CREATE TABLE table(col1,col2,... ); Luo uuden taulun. CREATE TABLE opiskelijat(opnumero,etunimi,sukunimi);

Tietokantojen suunnittelu, relaatiokantojen perusteita

Esimerkki. pankkien talletus- ja lainatietokanta: Yhdiste, leikkaus, erotus ym. Leikkaus (intersect) Yhdiste (Union) Erotus (except/minus) Leikkaus

Harjoituksen aiheena on tietokantapalvelimen asentaminen ja testaaminen. Asennetaan MySQL-tietokanta. Hieman linkkejä:

Tietokannat. CREATE TABLE table(col1,col2,... ); Luo uuden taulun. CREATE TABLE opiskelijat(opnumero,etunimi,sukunimi);

Muita tietokantaobjekteja. Näkymät, synonyymit, indeksointi, valtuudet ja systeemihakemisto

Yhdiste, leikkaus, erotus ym.

MUITA TIETOKANTAOBJEKTEJA NÄKYMÄT, SYNONYYMIT, INDEKSOINTI, VALTUUDET JA SYSTEEMIHAKEMISTO

Kirjasto Relaatiotietokannat Kevät Auvinen Annemari Niemi Anu Passoja Jonna Pulli Jari Tersa Tiina

Tietokannat. CREATE TABLE table(col1,col2,... ); Luo uuden taulun. CREATE TABLE opiskelijat(opnumero,etunimi,sukunimi);

CS-A1150 Tietokannat CS-A1150 Tietokannat / 39

4.3.4 SQL kyselyt... 45

Tiedonhallinnan perusteet. Viikko 1 Jukka Lähetkangas

OpenOffice.org Base 3.1.0

CS-A1150 Tietokannat CS-A1150 Tietokannat / 44

ASTERI-OHJELMIEN SQL-ERIKOISKURSSI LUENTOKALVOT

Ohjelmoinnin perusteet Y Python

Helsingin yliopisto/ tktl D Tietokantojen perusteet, s 2000 Relaatioalgebra. Harri Laine 1. Relaatioalgebra.

Taulukot. Jukka Harju, Jukka Juslin

Tietokannat II -kurssin harjoitustyö

TIETOKANNAT JOHDANTO

Python-ohjelmointi Harjoitus 2

KOOSTEFUNKTIOT. Viisi standardifunktiota: Esim. montako henkilöä on henkilo-taulussa:

VINKKI: Katso Kentät Muistioon -painikkeella, mikä on taulukon nimen oikea kirjoitusasu.

4.3.1 SQL tietokanta SQL:n kirjoitusasu SQL määrittelykielenä... 36

Tällä viikolla. Kotitehtävien tarkistus Upotettu SQL Indeksi-harjoitus täydennetään pelifirman tietokantamallia SQL-tehtäviä

2. Käsiteanalyysi ja relaatiomalli

Proseduurit, funktiot ja herättimet - esimerkkeinä Oracle, SQL Server, MySQL ja OCELOT. Jouni Huotari S2008

PROSEDUURIT, FUNKTIOT JA HERÄTTIMET - ESIMERKKEINÄ ORACLE, SQL SERVER, MYSQL JA OCELOT JOUNI HUOTARI K2009

ITKA204 Tietokannat ja tiedonhallinnan perusteet

Tietokannan hallinta. Kevät 2004 Jan Lindström R&G Chapter 1

HAAGA-HELIA TIKO - Heti09 1 (22) ICT05 Tiedonhallinta ja Tietokannat E.Räty, O.Virkki, M.Laiho

TIETOKANTOJEN PERUSTEET OSIO 11 MARKKU SUNI

Java-kielen perusteet

Transkriptio:

Luku 4 SQL 4.1 Yleistä SQL:stä 4.2 SQL-lauseet 4.3 DML: datan hallinta 4.4 DDL: rakenteen määrittäminen 4.5 DCL: valtuuttaminen 4.6 TxCL: tapahtumanhallinta ITKA204 kevät 2016 1

4.1 Yleistä SQL:stä Structured Query Language SQL on ANSI/ISO-standardiin perustuva korkean tason kyselykieli relaatiotietokantoihin. Juuret 1970-luvun lopulla: IBM:n System R:n SEQUEL ja RSI:n Oraclen SQL. SQL-standardista julkaistu useita versioita: 1986, 1989, 1992, 1999, 2003, 2006, 2008, 2011. Suuri osa SQL-kielestä on standardisoitu, loput kielestä perustuu vakiintuneisiin käytäntöihin. Suunniteltu alun perin yksinkertaiseksi kieleksi yksinkertaisten operaatioiden suorittamiseen. Teoreettinen perusta Coddin relaatiomallissa ja siihen kuuluvassa relaatioalgebrassa. Kieli jaetaan yleisesti neljään osaan: Datan hallinta (Data Management Language, DML) Rakenteen määrittäminen (Data Definition Language, DDL) Valtuuttaminen (Data Control Language, DCL) Tapahtumanhallinta (Transaction Control Language, TxCL) Standardoimisen johdosta eri RDBMS:t toimivat SQL:n osalta hyvin samankaltaisesti. ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 2

4.1 Yleistä SQL:stä Yhtäläisyydet relaatiomalliin Vaikka SQL-standardi perustuu relaatiomalliin, niissä on joitakin eroja, mm.: SQL-standardi esittelee suuren määrän toiminnallisuutta, joka ei kuulu relaatiomalliin. SQL sallii mm. moniarvoiset attribuutit. SQL:ssä relaation monikoiden (taulun rivien) sallitaan olevan samanlaiset. Kieltä onkin kritisoitu relaatiomallista poikkeamisesta. SQL:n nimeämiskäytänteet vastaavat suurpiirteisesti seuraavia relaatiomallin käsitteitä: Relaatiomalli relaatio (relation) attribuutti (attribute) monikko (tuple) SQL taulu (table) sarake (column) rivi (row) SQL:n osalta tietomallin voikin hahmottaa joukkona tauluja ja eheysrajoitteita sekä kyselykielenä. ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 3

4.1 Yleistä SQL:stä Käyttö Luvussa 2 esiteltiin kyselykielen käyttöä eri tavoin: upottamalla kyselykieltä isäntäkieleen (esim. Java, C#, Python, Haskell), kutsumalla isäntäkielessä tietokantaan tallennettua rutiinia (esim. PL/SQL tai T/SQL), kokonaan isäntäkielellä (ns. natiivikyselynä) tai ORM (object-relational mapper) työkaluja käyttäen. Tämän lisäksi kyselykieltä voidaan käyttää DBMS:n SQL-rajapinnan kautta. Tämä soveltuu erityisen hyvin SQL:n opetteluun tai yksittäisten operaatioiden suorittamiseen. Tätä lähestymistapaa käytetään myös tällä kurssilla. ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 4

4.2 SQL-lauseet Yleiset säännöt SQL-operaatiota kutsutaan yleisesti SQL-lauseeksi. SQL-lause koostuu SQL-avainsanoista (kuten SELECT tai ORDER BY), tietokantaobjektien (kuten taulut, näkymät ja indeksit) nimistä, ehtolausekkeista (kuten ikä > 30) ja päättyy puolipisteeseen ; Kirjainkoolla ei ole merkitystä SQL-avainsanoissa tai tietokantaobjektien nimissä. Tietokantaobjektien nimissä voidaan käyttää kirjaimia (a-z), numeroita ja alaviivaa. Tietokantaobjektin nimi ei kuitenkaan voi alkaa numerolla, eikä varattuja sanoja voi käyttää. Rivivaihdoilla ei ole merkitystä. Tällä kurssilla käsitellään SQL:ää SQL-standardin näkökulmasta. ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 5

Yleistä DML:stä DML (Data Management Language) lienee tarkimmin standardoitu SQL:n alikieli. DML:n avulla voidaan suorittaa yleisimmät SQL-lauseet, eli datan: etsiminen (SELECT), lisääminen (INSERT), muokkaaminen (UPDATE) ja poistaminen (DELETE). Tällä kurssilla käsitellään suuri osa DML-kielestä. DML lienee SQL:n osalta kurssin vaativin osa-alue. ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 6

Materiaalin syntaksimerkinnät SQL-avainsanat on kirjoitettu suuraakkosilla. Tietokantaobjektien nimet on kirjoitettu pienillä kirjaimilla. Hakasulkeet [ ] ryhmittävät lauseen osia. Hakasulkeita seuraa Backus/Naur-muodon mukainen kardinaalisuusmerkintä, joka kertoo hakasulkujen sisällön pakollisuudesta: + = 1..n toistoa * = 0..n toistoa? = 0..1 toistoa Pystyviiva kertoo vaihtoehtoisuudesta, esim. [ASC DESC]? = joko ASC tai DESC tai ei kumpaakaan. Hakasulkeita, kardinaalisuusmerkintöjä tai pystyviivoja ei kirjoiteta varsinaiseen SQL-lauseeseen. ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 7

Harjoitustietokannan kaava Tässä alaluvussa käytetään harjoitustietokantana seuraavaa, ellei toisin mainita: ASIAKAS ( astun, asnimi, kaup, tyyppi, mpiiri ) LASKU ( laskuno, vuosi, lask_summa, tila, astun ) LASKU_RIVI ( laskuno, tuotetun, maara ) TUOTE ( tuotetun, tuotenimi, malli, ahinta, vari ) CHAR ja VARCHAR = merkkijono INT = kokonaisluku ASIAKAS LASKU LASKU_RIVI TUOTE astun CHAR(4) laskuno CHAR(4) laskuno CHAR(4) tuotetun CHAR(4) asnimi VARCHAR(15) vuosi INT tuotetun CHAR(4) tuotenimi VARCHAR(15) kaup VARCHAR(10) lask_summa INT maara INT malli VARCHAR(10) tyyppi VARCHAR(10) tila VARCHAR(2) ahinta INT mpiiri VARCHAR(10) astun CHAR(4) vari VARCHAR(10) ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 8

Hakulauseen yleinen muoto SELECT-lause on SQL-hakulause. Se koostuu yksinkertaisimmillaan kahdesta osasta: SELECT-osa: mitä sarakkeita tulostauluun halutaan. Tulostaulun otsake muodostuu näistä sarakkeista. FROM-osa: mistä tauluista data noudetaan. SELECT sarake[, sarake]* FROM taulu[, taulu]*; SELECT astun, asnimi, kaup, tyyppi, mpiiri FROM asiakas; ASIAKAS astun CHAR(4) asnimi VARCHAR(15) kaup VARCHAR(10) tyyppi VARCHAR(10) astun asnimi kaup tyyppi mpiiri mpiiri VARCHAR(10) a101 Kojo JKL y k a102 Laippa TRE h i a104 Kajo JKL h l ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 9

Vertailuoperaattorit Hakuehdot asetetaan hakulauseen vapaaehtoiseen WHERE-osaan. Lukuarvojen vertailuun käytetään operaattoreita <, >, <=, >= ja = Lukuarvojen erisuuruutta voidaan tarkastaa operaattoreilla <> ja!= Ehtolausekkeita voidaan yhdistää loogisilla operaattoreilla AND ja OR. SELECT sarake[, sarake]* FROM taulu[, taulu]* [WHERE ehtolauseke[ operaattori ehtolauseke]*]?; SELECT * FROM tuote WHERE ahinta > 100 AND ahinta <= 2000; TUOTE tuotetun CHAR(4) tuotenimi VARCHAR(15) malli VARCHAR(10) ahinta INT vari VARCHAR(10) ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 10

Merkkijonojen vertailu Merkkijonoja vertaillaan [NOT] LIKE predikaatilla. Vertailtava merkkijono kirjoitetaan heittomerkkien väliin. Vertailussa voidaan käyttää jokerimerkkejä: Alaviiva vastaa yhtä mitä tahansa merkkiä Prosenttimerkki vastaa 0..n mitä tahansa merkkiä. SELECT mpiiri, tyyppi FROM asiakas WHERE asnimi LIKE 'Kajo'; ASIAKAS astun CHAR(4) asnimi VARCHAR(15) kaup VARCHAR(10) tyyppi VARCHAR(10) mpiiri VARCHAR(10) SELECT asnimi, tyyppi, mpiiri FROM asiakas WHERE asnimi NOT LIKE K% AND kaup LIKE _y% ; Hae niiden asiakkaiden nimi, tyyppi ja myyntipiiri, joiden nimi ei ala K-kirjaimella ja joiden asuinkaupungin toinen kirjain on y. ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 11

Suoritusjärjestys Ehtolausekkeiden suoritusjärjestystä voidaan ohjata sulkeilla. Pelkkää AND-operaattoria käytettäessä ehtojen järjestyksellä ei ole tulosten kannalta merkitystä. AND on OR:iin nähden etuoikeutettu. SELECT * FROM asiakas WHERE tyyppi LIKE y AND (mpiiri LIKE i OR mpiiri LIKE k ); SELECT * FROM asiakas WHERE tyyppi LIKE y AND mpiiri LIKE i OR mpiiri LIKE k ; Hae niiden asiakkaiden kaikki tiedot, jotka ovat yritysasiakkaita ja joiden myyntipiiri on joko itä tai keski. Hae niiden asiakkaiden kaikki tiedot, jotka ovat yritysasiakkaita itäisestä myyntipiiristä sekä kaikkien keskimyyntipiirin asiakkaiden tiedot. ASIAKAS astun CHAR(4) asnimi VARCHAR(15) kaup VARCHAR(10) tyyppi VARCHAR(10) mpiiri VARCHAR(10) ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 12

Tyhjäarvon tarkastaminen Tyhjäarvon esiintymistä tarkastetaan SQL:ssä IS [NOT] NULL predikaatilla. SELECT tuotenimi FROM tuote WHERE ahinta IS NULL; SELECT tuotenimi FROM tuote WHERE malli IS NOT NULL; TUOTE tuotetun CHAR(4) tuotenimi VARCHAR(15) malli VARCHAR(10) ahinta INT vari VARCHAR(10) EI NÄIN: EIKÄ NÄIN: ET TEE NÄIN: ETKÄ NÄIN: SELECT tuotenimi FROM tuote WHERE ahinta = NULL; SELECT tuotenimi FROM tuote WHERE ahinta = 0; SELECT tuotenimi FROM tuote WHERE malli LIKE ; SELECT tuotenimi FROM tuote WHERE malli LIKE NULL ; ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 13

Muita tapoja vertailuun [NOT] BETWEEN predikaatti. Tarkastetaan, onko vertailtava arvo annetulla välillä. sarake BETWEEN arvo1 AND arvo2 SELECT tuotenimi FROM tuote WHERE ahinta BETWEEN 100 AND 200; = SELECT tuotenimi FROM tuote WHERE ahinta >= 100 AND ahinta <= 200; ASIAKAS astun CHAR(4) asnimi VARCHAR(15) kaup VARCHAR(10) tyyppi VARCHAR(10) mpiiri VARCHAR(10) [NOT] IN predikaatti. Tarkastetaan, kuuluuko vertailtava arvo esitettyyn joukkoon. Jokerimerkkejä ei voida käyttää. sarake IN (pilkkulista) SELECT tuotenimi FROM tuote WHERE mpiiri IN ( i, e ); = SELECT tuotenimi FROM tuote WHERE mpiiri LIKE i OR mpiiri LIKE e ; ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 14

Tulosten järjestäminen Tulostaulu voidaan järjestää vapaaehtoisella ORDER BY osalla. Lisämääre ASC (ascending) järjestää tulokset nousevaan (A Z) järjestykseen. Tämä on oletus. Lisämääre DESC (descending) järjestää tulokset laskevaan järjestykseen (Z A). ASIAKAS SELECT sarake[, sarake]* FROM taulu[, taulu]* [WHERE ehtolauseke[ operaattori ehtolauseke]*]? [ORDER BY sarake[ ASC DESC]?[, sarake[ ASC DESC]?]*]?; SELECT asnimi, kaup, tyyppi FROM asiakas WHERE mpiiri LIKE i ORDER BY asnimi; astun CHAR(4) asnimi VARCHAR(15) kaup VARCHAR(10) tyyppi VARCHAR(10) mpiiri VARCHAR(10) SELECT asnimi, kaup, tyyppi FROM asiakas ORDER BY asnimi DESC, kaup ASC, tyyppi DESC; ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 15

Haku useasta taulusta Relaatiotietokannassa haluttu tieto on tavallisesti jaettu eri relaatioihin. Asiakkaan tiedot ovat yhdessä taulussa, hänen tilauksensa toisessa jne. Tästä syystä useampaa kuin yhtä taulua koskevat hakulauseet ovat yleisiä. Tarkastellaan seuraavaksi useaan tauluun kohdistuvia hakulauseita. Tärkein yksittäinen asia useampaa kuin yhtä taulua koskevassa lauseessa on liitos. Liitoksen voi lähtökohtaisesti toteuttaa neljällä eri tavalla: 1. Alikyselynä käyttäen IN-predikaattia (toimii kolmiarvoisella logiikalla). 2. Alikyselynä käyttäen EXISTS-predikaattia (toimii kaksiarvoisella logiikalla). 3. Yksitasoisena ilman alikyselyä. 4. JOIN-predikaatilla. ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 16

Liitos Tarkoituksena on tavallisesti löytää sarakkeiden yhteiset arvot kahdesta taulusta. Liitos toteutetaan tavallisesti viiteavaimia (viittaavaa ja viitattua) vertailemalla. Lasku_rivi-taulu: niiden tuotteiden tuotetunnukset, joista on joskus laskutettu. lasku_rivi laskuno tuotetun määrä l200 t101 1 l200 t104 2 l201 t101 3 l202 t107 1 l202 t104 Tuote-taulu: kaikkien tuotteiden tiedot. tuote tuotetun tuotenimi t101 t104 t105 t106 t107 Jollotin Kooppari Kukerrin Tukaani Furniture Yhteiset tuotetunnukset: t101 t104 t107 Ts. tuotteet, joista on joskus laskutettu. ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 17

Alikysely IN-predikaatilla 1. Liitos voidaan toteuttaa alikyselynä käyttäen IN-predikaattia Kuten aikaisemmin esitettiin, IN-predikaatilla voidaan tarkastaa, kuuluuko vertailtava arvo johonkin joukkoon. Alikyselyssä IN-predikaatille ei anneta eksplisiittisesti vertailtavaa joukkoa, vaan joukko muodostetaan alikyselyn avulla. LASKU_RIVI TUOTE Pääkysely Alikysely SELECT tuotenimi FROM tuote WHERE tuotetun IN (SELECT tuotetun FROM lasku_rivi); Hae niiden tuotteiden nimet, joista on joskus laskutettu, ts. joita on joskus tilattu, ts. joita koskee ainakin yksi laskurivi. laskuno CHAR(4) tuotetun CHAR(4) maara INT tuotetun CHAR(4) tuotenimi VARCHAR(15) malli VARCHAR(10) ahinta INT vari VARCHAR(10) Jos oletetaan, että laskutettuja tuotteita ovat t101 ja t120, kysely voisi ajon aikana sieventyä näin: SELECT tuotenimi FROM tuote WHERE tuotetun IN ( t101, t120 ); HUOM. tämä ei ole tapa tehdä liitoksia, vaan havainnollistava esimerkki. ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 18

Alikysely IN-predikaatilla IN-predikaatti ei tarvitse eksplisiittistä liitosehtoa, vaan liitos muodostetaan IN-predikaatin molemmin puolin. SELECT tuotenimi FROM tuote WHERE tuotetun IN (SELECT tuotetun FROM lasku_rivi); SELECT vuosi, lask_summa FROM lasku WHERE laskuno IN (SELECT laskuno FROM lasku_rivi WHERE tuotetun IN (SELECT tuotetun FROM tuote WHERE vari LIKE punainen ) ); lasku_rivi-taulun tuotetunsarakkeen arvo vastaa tuote-taulun tuotetun-sarakkeen jotakin arvoa. Hae niiden laskujen vuodet ja summat, jotka koskevat ainakin yhtä punaista tuotetta. LASKU_RIVI laskuno CHAR(4) tuotetun CHAR(4) maara INT LASKU laskuno CHAR(4) vuosi INT lask_summa INT tila VARCHAR(2) astun CHAR(4) TUOTE tuotetun CHAR(4) tuotenimi VARCHAR(15) malli VARCHAR(10) ahinta INT vari VARCHAR(10) ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 19

Alikysely IN-predikaatilla SELECT vuosi, lask_summa FROM lasku WHERE laskuno IN (SELECT laskuno FROM lasku_rivi WHERE tuotetun IN (SELECT tuotetun FROM tuote WHERE vari LIKE punainen ) ); TUOTE tuotetun CHAR(4) tuotenimi VARCHAR(15) malli VARCHAR(10) ahinta INT vari VARCHAR(10) LASKU_RIVI laskuno CHAR(4) tuotetun CHAR(4) maara INT LASKU laskuno CHAR(4) vuosi INT lask_summa INT tila VARCHAR(2) astun CHAR(4) tuote lasku_rivi lasku vari tuotetun tuotetun laskuno laskuno vuosi lask_summa punainen t210 t299 l400 l400 2002 4700 hyväksytään. punainen t222 t222 l400 l401 2003 3000 hyväksytään. sininen t299 t222 l401 l402 2002 1800 hylätään. ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 20

Näkyvyysalue FROM-osissa esiteltyjen taulujen sarakkeisiin voidaan viitata sisemmissä alikyselyissä. Alikyselyiden FROM-osissa esiteltyjen taulujen sarakkeisiin ei voida viitata ulomman tason kyselyissä. Pääkysely. Tässä ei voida viitata alikyselyiden taulujen sarakkeisiin. Alikysely 1. Tässä voidaan viitata pääkyselyn taulun sarakkeisiin, mutta ei alikysely 2:n taulun. SELECT tuotenimi FROM tuote WHERE tuotetun IN (SELECT tuotetun FROM lasku_rivi WHERE laskuno IN (SELECT laskuno FROM lasku) ); Alikysely 2. Tässä voidaan viitata pääkyselyn ja alikysely 1:n taulujen sarakkeisiin. ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 21

Luentotehtävä 3 Esitä seuraava kysely SQL-kielellä (voit käyttää apuna TIM:n tietokantaa): Hae niiden yritysasiakkaiden nimet ja kaupungit, jotka eivät ole Kouvolasta ja joita on laskutettu vuonna 2014. Asiakkuuden tyyppi on tallennettu muodossa y tai h (yritys- tai henkilöasiakas). [ Tuloksena: <Virtanen, Mikkeli> ja <Kassakko, Helsinki> ] ASIAKAS LASKU LASKU_RIVI TUOTE astun CHAR(4) laskuno CHAR(4) laskuno CHAR(4) tuotetun CHAR(4) asnimi VARCHAR(15) vuosi INT tuotetun CHAR(4) tuotenimi VARCHAR(15) kaup VARCHAR(10) lask_summa INT maara INT malli VARCHAR(10) tyyppi VARCHAR(10) tila VARCHAR(2) ahinta INT mpiiri VARCHAR(10) astun CHAR(4) vari VARCHAR(10) ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 22

Luentotehtävä 3: ratkaisu Hae niiden yritysasiakkaiden nimet ja kaupungit, jotka eivät ole Kouvolasta ja joita on laskutettu vuonna 2014. ASIAKAS LASKU LASKU_RIVI TUOTE astun CHAR(4) laskuno CHAR(4) laskuno CHAR(4) tuotetun CHAR(4) asnimi VARCHAR(15) vuosi INT tuotetun CHAR(4) tuotenimi VARCHAR(15) kaup VARCHAR(10) lask_summa INT maara INT malli VARCHAR(10) tyyppi VARCHAR(10) tila VARCHAR(2) ahinta INT mpiiri VARCHAR(10) astun CHAR(4) vari VARCHAR(10) SELECT asnimi, kaup FROM asiakas WHERE tyyppi LIKE y AND kaup NOT LIKE Kouvola AND astun IN (SELECT astun FROM lasku WHERE vuosi = 2014); ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 23

Tarkentimet Kahdessa tai useammassa taulussa voi olla saman nimisiä sarakkeita. Niihin tulee viitata yksiselitteisesti tarkentimilla. Tarkennin voi olla joko taulun nimi tai itse määritelty lauseen FROM-osassa. SELECT sarake[, sarake]* FROM taulu[ tarkennin]?[, taulu[ tarkennin]?]* [WHERE ehtolauseke[ operaattori ehtolauseke]*]? [ORDER BY sarake[ ASC DESC]?[, sarake[ ASC DESC]?]*]?; ASIAKAS astun CHAR(4) asnimi VARCHAR(15) kaup VARCHAR(10) tyyppi VARCHAR(10) mpiiri VARCHAR(10) SELECT asiakas.asnimi FROM asiakas, lasku WHERE asiakas.astun = lasku.astun AND asiakas.astun LIKE a101 ; SELECT a.asnimi FROM asiakas a, lasku l WHERE a.astun = l.astun AND a.astun LIKE a101 ; EI TOIMI: SELECT asnimi FROM asiakas, lasku WHERE astun = astun AND astun LIKE a101 ; LASKU laskuno CHAR(4) vuosi INT lask_summa INT tila VARCHAR(2) astun CHAR(4) ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 24

Alikysely EXISTS-predikaatilla 2. Liitos voidaan toteuttaa alikyselynä käyttäen EXISTS-predikaattia. EXISTS-predikaatti tarvitsee eksplisiittisen liitosehdon. Liitos muodostetaan aina alikyselyssä. Alikyselyn SELECT-osan valinnalla ei ole merkitystä, tavallisesti käytetään joko numeroa yksi tai tähtimerkkiä. SELECT t.tuotenimi FROM tuote t WHERE EXISTS (SELECT * FROM lasku_rivi lr WHERE t.tuotetun = lr.tuotetun); Hae niiden tuotteiden nimet, joita koskee ainakin yksi laskurivi. LASKU_RIVI laskuno CHAR(4) tuotetun CHAR(4) maara INT TUOTE tuotetun CHAR(4) tuotenimi VARCHAR(15) malli VARCHAR(10) ahinta INT vari VARCHAR(10) ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 25

Alikysely EXISTS-predikaatilla SELECT t.tuotenimi FROM tuote t WHERE EXISTS (SELECT * FROM lasku_rivi lr WHERE t.tuotetun = lr.tuotetun); SELECT l.vuosi, l.lask_summa FROM lasku l WHERE EXISTS (SELECT * FROM lasku_rivi lr WHERE l.laskuno = lr.laskuno AND EXISTS (SELECT * FROM tuote t WHERE lr.tuotetun = t.tuotetun AND t.vari LIKE punainen ) ); = = SELECT tuotenimi FROM tuote WHERE tuotetun IN (SELECT tuotetun FROM lasku_rivi); SELECT vuosi, lask_summa FROM lasku WHERE laskuno IN (SELECT laskuno FROM lasku_rivi WHERE tuotetun IN (SELECT tuotetun FROM tuote WHERE vari LIKE punainen ) ); TUOTE tuotetun CHAR(4) tuotenimi VARCHAR(15) malli VARCHAR(10) ahinta INT vari VARCHAR(10) LASKU_RIVI laskuno CHAR(4) tuotetun CHAR(4) maara INT LASKU laskuno CHAR(4) vuosi INT lask_summa INT tila VARCHAR(2) astun CHAR(4) ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 26

Yksitasoinen liitos 3. Liitos voidaan toteuttaa yksitasoisena ilman alikyselyitä. Liitosehto annetaan eksplisiittisesti lauseen WHERE-osassa. Toimintalogiikka sama kuin EXISTS-predikaatilla. SELECT t.tuotenimi FROM tuote t, lasku_rivi lr WHERE t.tuotetun = lr.tuotetun; SELECT l.vuosi, l.lask_summa FROM tuote t, lasku_rivi lr, lasku l WHERE t.tuotetun = lr.tuotetun AND lr.laskuno = l.laskuno AND t.vari LIKE punainen ; Lauseet vastaavat edellisen kalvon lauseita, jos liitosehdot toteuttavissa sarakkeissa ei ole tyhjäarvoja. HUOM. kaikki lauseita ei voi toteuttaa yksitasoisena, esim. ei-ole-olemassa-tapaus ja koostefunktioihin perustuva liitos. Näitä käsitellään myöhemmin. TUOTE tuotetun CHAR(4) tuotenimi VARCHAR(15) malli VARCHAR(10) ahinta INT vari VARCHAR(10) LASKU_RIVI laskuno CHAR(4) tuotetun CHAR(4) maara INT LASKU laskuno CHAR(4) vuosi INT lask_summa INT tila VARCHAR(2) astun CHAR(4) ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 27

Toisteisten rivien hylkääminen Jos jokaisesta tulostaulun rivistä halutaan uniikki, voidaan käyttää DISTINCT-lisämäärettä. Erilaiset liitokset (erityisesti yksitasoinen liitos) voivat tuottaa duplikaattirivejä tulostauluun. DISTINCT-lisämääre sijoitetaan tässä tapauksessa lauseen SELECT-avainsanan jälkeen. DISTINCT-lisämäärettä voidaan käyttää myös koostefunktioissa (esitellään myöhemmin). SELECT DISTINCT t.tuotenimi FROM tuote t, lasku_rivi lr WHERE t.tuotetun = lr.tuotetun; ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 28

Liitos JOIN-predikaatilla 4. Liitos voidaan toteuttaa JOIN-predikaatilla. JOIN-predikaatti eli sisäliitos on standardin versiossa SQL-92 lisätty tapa toteuttaa liitoksia. JOIN-predikaatti on syntaksiltaan vähemmän virhealtis kuin muut esitellyt liitostavat. SELECT sarake[, sarake]* FROM taulu [tarkennin]? [[INNER]? JOIN taulu [tarkennin]? ON liitosehto]+ [WHERE ehtolauseke[ operaattori ehtolauseke]*]? [ORDER BY sarake[ ASC/DESC]?[, sarake[ ASC/DESC]]*]?; SELECT l.vuosi, l.lask_summa FROM tuote t JOIN lasku_rivi lr ON t.tuotetun = lr.tuotetun JOIN lasku l ON lr.laskuno = l.laskuno WHERE t.vari LIKE punainen ; TUOTE tuotetun CHAR(4) tuotenimi VARCHAR(15) malli VARCHAR(10) ahinta INT vari VARCHAR(10) LASKU_RIVI laskuno CHAR(4) tuotetun CHAR(4) maara INT LASKU laskuno CHAR(4) vuosi INT lask_summa INT tila VARCHAR(2) astun CHAR(4) ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 29

Kyselyn suunnittelu 1. Ensin on syytä tarkastella tietokannan kaavaa ja tunnistaa ne taulut, joista tietoa halutaan tulostauluun. 2. Seuraavaksi etsitään ne taulut, joiden sarakkeisiin täytyy kohdistaa ehtolausekkeita, tällaisia ehtolausekkeita kutsutaan myös sisällöllisiksi ehdoiksi. 3. Seuraavaksi tarkastellaan, mitä muita tauluja mahdollisesti tarvitaan, jotta jo kyselyn kannalta relevanteiksi luokitellut taulut voidaan liittää liitosehdoilla. 4. Valitaan mahdolliset tarkentimet. Jos lauseessa käytetään tarkentimia, on suositeltavaa käyttää niitä koko lauseessa, vaikka jokin sarake se sellaista välttämättä tarvitsisikaan. 5. Ennen varsinaisen lauseen kirjoittamista täytyy tunnistaa, millä sarakkeilla liitosehdot voidaan tehdä. Suunnittele esim. piirtämällä. 6. Lopuksi kirjoitetaan kysely. ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 30

Koostefunktiot Koostefunktioita (aggregate function) käytetään laskutoimitusten suorittamiseen. Niille annetaan tavallisesti yksi parametri, ja ne palauttavat yhden arvon. Koostefunktiot ovat minimi (MIN), maksimi (MAX), keskiarvo (AVG), summa (SUM) ja lukumäärä (COUNT). SUM käsittelee tyhjäarvoa kuten nollaa: 2+4+NULL+2 = 8. COUNT laskee vain sarakkeesta vain ne rivit (solut), joissa ei ole tyhjäarvoa: Matti + Teppo +NULL = 2. Koostefunktiot sijoitetaan lauseen SELECT- tai HAVING-osaan (esitellään myöhemmin). I Ei koostefunktioita WHERE-osaan. TYÖNTEKIJÄ ttnro palkka sukunimi t001 1000 Jantunen t002 2000 Kilpiö t003 2000 Sammal t004 3000 Räikkönen t005 Lassila Funktio Palauttaa arvon COUNT(palkka) 4 SUM(palkka) 8000 AVG(palkka) 2000 MAX(palkka) 3000 MIN(palkka) 1000 COUNT(DISTINCT palkka) 3 ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 31

Koostefunktiot AS-predikaatilla voidaan tarvittaessa nimetä tulostaulun sarakkeet kuvaavammin. COUNT(*) laskee taulun rivien lukumäärän. SELECT COUNT(DISTINCT kaup) AS kaupunkien lukumaara FROM asiakas; ASIAKAS astun CHAR(4) asnimi VARCHAR(15) kaup VARCHAR(10) tyyppi VARCHAR(10) mpiiri VARCHAR(10) TUOTE tuotetun CHAR(4) SELECT MAX(t.ahinta) - MIN(t.ahinta) AS hintaero FROM tuote t, lasku_rivi lr WHERE t.tuotetun = lr.tuotetun AND lr.maara > 1; SELECT SUM(ahinta)*1.22 AS yhteensa (plus alv) FROM tuote WHERE tuotenimi IS NOT NULL; SELECT COUNT(*) AS yritysasiakkaiden lukumäärä FROM asiakas WHERE tyyppi LIKE y ; Huomaa laskenta SELECT-osassa. Laskutoimituksia voidaan tehdä ilman koostefunktioitakin. tuotenimi VARCHAR(15) malli VARCHAR(10) ahinta INT vari VARCHAR(10) LASKU_RIVI laskuno CHAR(4) tuotetun CHAR(4) maara INT ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 32

Ryhmittely Koostefunktioiden tuloksia täytyy usein ryhmitellä jonkin toisen sarakkeen mukaan. Esim. tuotehintojen keskiarvot tuoteväreittäin. Ryhmittely tapahtuu GROUP BY määreellä, joka sijoittuu lauseessa heti WHERE-osan jälkeen. Ryhmittely vaatii, että ainakin yksi tulostaulun sarake on muodostettu ilman koostefunktiota (ns. ryhmittelevä sarake). Jos tulostaulussa on lisäksi ainakin yksi koostefunktion muodostama sarake, täytyy ryhmittely tehdä jokaisen ryhmittelevän sarakkeen mukaan. SELECT sarake[, sarake]* FROM taulu [tarkennin]?[, taulu [tarkennin]?]* [WHERE ehtolauseke[ operaattori ehtolauseke]*]? [GROUP BY sarake[, sarake]*]? [ORDER BY sarake[ ASC DESC]?[, sarake[ ASC DESC]]*]?; ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 33

Ryhmittely SELECT SUM(ahinta) AS hinta_yht, vari FROM tuote GROUP BY vari; hinta_yht vari 97 harmaa 2001 musta SELECT tyyppi, kaup, COUNT(*) AS asiakkaita 110 punainen FROM asiakas GROUP BY tyyppi, kaup; tyyppi kaup asiakkaita h Helsinki 15 h Jyväskylä 9 y Helsinki 2 y Jyväskylä 10 SELECT COUNT(*) AS asiakkaita, kaup FROM asiakas a, lasku l WHERE a.astun = l.astun GROUP BY kaup ORDER BY asiakkaita; Hae kaupungeittain sellaisten asiakkaiden lukumäärä, joita koskee ainakin yksi lasku. Järjestä tulokset asiakkaiden lukumäärän mukaan nousevaan järjestykseen. ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 34

II Ryhmittely SELECT SUM(ahinta) FROM tuote; Jos yksikin tulostaulun sarake on koostefunktion muodostama, ryhmittely on tehtävä jokaisen ryhmittelevän sarakkeen mukaan. SELECT tuotenimi FROM tuote; Oikein. SELECT SUM(ahinta), AVG(ahinta) FROM tuote; SELECT SUM(ahinta), vari FROM tuote; VÄÄRIN. Ei ryhmitelty värin mukaan. SELECT malli, SUM(ahinta), vari FROM tuote GROUP BY vari; VÄÄRIN. Ei ryhmitelty mallin mukaan. ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 35

Ryhmittely Joskus ryhmiteltyjä tuloksia täytyy rajata koostefunktion tuottaman arvon perusteella. Rajaus tehdään HAVING-osalla, joka sijoittuu GROUP BY- ja ORDER BY osien väliin. SELECT sarake[, sarake]* FROM taulu [tarkennin]?[, taulu [tarkennin]?]* [WHERE ehtolauseke[ operaattori ehtolauseke]*]? [GROUP BY sarake[, sarake]*]? [HAVING ehtolauseke[ operaattori ehtolauseke]*]? [ORDER BY sarake[ ASC DESC]?[, sarake[ ASC DESC]]*]?; SELECT COUNT(*) AS asiakkaita, a.kaup FROM asiakas a, lasku l WHERE a.astun = l.astun GROUP BY kaup HAVING COUNT(*) > 3; Hae kaupungeittain sellaisten asiakkaiden lukumäärä, joita koskee ainakin yksi lasku. Ota tuloksiin mukaan vain ne kaupungit, joissa asuu enemmän kuin kolme ehdot täyttävää asiakasta. ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 36

Luentotehtävä 4 Esitä seuraavat kyselyt SQL-kielellä: a) Hae asiakkaita koskevien laskujen määrä asiakkaittain (asnimi). Rajaa tulokset niihin asiakkaisiin, joita koskee yli kaksi laskua. b) Hae laskutettujen tuotteiden kappalemäärät vuosittain ja tuoteväreittäin. ASIAKAS LASKU LASKU_RIVI TUOTE astun CHAR(4) laskuno CHAR(4) laskuno CHAR(4) tuotetun CHAR(4) asnimi VARCHAR(15) vuosi INT tuotetun CHAR(4) tuotenimi VARCHAR(15) kaup VARCHAR(10) lask_summa INT maara INT malli VARCHAR(10) tyyppi VARCHAR(10) tila VARCHAR(2) ahinta INT mpiiri VARCHAR(10) astun CHAR(4) vari VARCHAR(10) ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 37

Luentotehtävä 4: ratkaisu a) Hae asiakkaita koskevien laskujen määrä asiakkaittain (asnimi). Rajaa tulokset niihin asiakkaisiin, joita koskee yli kaksi laskua. b) Hae laskutettujen tuotteiden kappalemäärät vuosittain ja tuoteväreittäin. SELECT a.asnimi, COUNT(l.laskuno) AS laskuja FROM asiakas a, lasku l WHERE a.astun = l.astun GROUP BY a.asnimi HAVING COUNT(l.laskuno) > 2; SELECT l.vuosi, t.vari, SUM(lr.maara) AS kpl FROM tuote t, lasku_rivi lr, lasku l WHERE t.tuotetun = lr.tuotetun AND lr.laskuno = l.laskuno GROUP BY l.vuosi, t.vari; ASIAKAS LASKU LASKU_RIVI TUOTE astun CHAR(4) laskuno CHAR(4) laskuno CHAR(4) tuotetun CHAR(4) asnimi VARCHAR(15) vuosi INT tuotetun CHAR(4) tuotenimi VARCHAR(15) kaup VARCHAR(10) lask_summa INT maara INT malli VARCHAR(10) tyyppi VARCHAR(10) tila VARCHAR(2) ahinta INT mpiiri VARCHAR(10) astun CHAR(4) vari VARCHAR(10) ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 38

Skalaarifunktiot Koostefunktioiden (jotka ovat standardoituja) lisäksi on olemassa joukko skalaarifunktioita. Skalaarifunktioiden olemassa olo, nimi ja toiminta riippuvat vahvasti tuotteesta. Yleisiä skalaarifunktioita ovat esim. Pyöristys ja katkaisu, esim. ROUND(55.9870, 2) ja TRUNCATE(3.1415926, 4). Tyyppimuunnokset, esim. TO_CHAR(100), TO_INT( 500 ), CAST(100) AS FLOAT) Merkkijonojen käsittely, esim. SUBSTRING(tilakoodi, FROM 1 FOR 5), UPPER( turska ) ja LOWER( NORJA ). Aikatiedon käsittely, esim. EXTRACT(YEAR FROM now()). SQL-rajapintaa voidaan myös käyttää laskutoimituksiin. SELECT 10 * 58 FROM dual; SELECT (SELECT ahinta FROM tuote WHERE tuotetun = 1000) + (SELECT ahinta FROM tuote WHERE tuotetun = 1008) FROM dual; ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 39

Tyypillisiä ongelmia: ei-ole-olemassa-tapaus Silloin tällöin tuloksiin halutaan taulun sellaiset rivit, joihin viittaavia arvoja ei löydy jostakin muusta taulusta. Vertailuun voidaan käyttää NOT EXISTS predikaattia, jonka alikysely palauttaa arvon false, jos yksikin ehdot täyttävä rivi löytyy tai true, jos yhtään ehdot täyttävää riviä ei löydy. NOT EXISTS vaatii aina eksplisiittisen liitosehdon! Vertailuun voidaan käyttää myös NOT IN predikaattia alikyselyn yhteydessä. Katso tarvittaessa edellisiä kalvoja IN- ja EXISTS-predikaattien toiminnasta ja syntaksista. Ei mahdollista yksitasoisella ratkaisulla! ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 40

Tyypillisiä ongelmia: ei-ole-olemassa-tapaus ASIAKAS LASKU LASKU_RIVI TUOTE astun CHAR(4) laskuno CHAR(4) laskuno CHAR(4) tuotetun CHAR(4) asnimi VARCHAR(15) vuosi INT tuotetun CHAR(4) tuotenimi VARCHAR(15) kaup VARCHAR(10) lask_summa INT maara INT malli VARCHAR(10) tyyppi VARCHAR(10) tila VARCHAR(2) ahinta INT mpiiri VARCHAR(10) astun CHAR(4) vari VARCHAR(10) SELECT a.asnimi FROM asiakas a WHERE NOT EXISTS (SELECT * FROM lasku l WHERE a.astun = l.astun); Hae sellaisten asiakkaiden nimet, joita ei ole koskaan (ts. ei kertaakaan) laskutettu. SELECT a.asnimi FROM asiakas a WHERE a.kaup LIKE Helsinki AND NOT EXISTS (SELECT * FROM lasku l WHERE a.astun = l.astun AND l.vuosi = 2011); Hae sellaisten helsinkiläisten asiakkaiden nimet, joita ei ole laskutettu kertaakaan vuonna 2011. SELECT t.tuotenimi FROM tuote t WHERE NOT EXISTS (SELECT * FROM lasku_rivi lr WHERE t.tuotetun = lr.tuotetun AND lr.maara > 10); Hae sellaisten tuotteiden nimet, joita ei ole koskaan tilattu yli kymmentä kappaletta kerralla. ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 41

Tyypillisiä ongelmia: ei-ole-olemassa-tapaus SELECT a.asnimi FROM asiakas a WHERE NOT EXISTS (SELECT * FROM lasku l WHERE a.astun = l.astun); SELECT a.asnimi FROM asiakas a WHERE a.kaup LIKE Helsinki AND NOT EXISTS (SELECT * FROM lasku l WHERE a.astun = l.astun AND l.vuosi = 2011); SELECT t.tuotenimi FROM tuote t WHERE NOT EXISTS (SELECT * FROM lasku_rivi lr WHERE t.tuotetun = lr.tuotetun AND lr.maara > 10); SELECT asnimi FROM asiakas WHERE astun NOT IN (SELECT astun FROM lasku); SELECT asnimi FROM asiakas WHERE kaup LIKE Helsinki AND astun NOT IN (SELECT astun FROM lasku WHERE vuosi = 2011); SELECT tuotenimi FROM tuote WHERE tuotetun NOT IN (SELECT tuotetun FROM lasku_rivi WHERE maara > 10); ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 42

Tyypillisiä ongelmia: ei-ole-olemassa-tapaus III Ei-ole-olemassa-tapaus vaatii aina alikyselyn. Tehtävä: hae sellaisten asiakkaiden nimet, joita ei ole laskutettu kertaakaan vuonna 2011. oikein: SELECT a.asnimi FROM asiakas a WHERE NOT EXISTS (SELECT * FROM lasku l WHERE a.astun = l.astun AND l.vuosi = 2011); oikein: SELECT asnimi FROM asiakas WHERE astun NOT IN (SELECT astun FROM lasku WHERE vuosi = 2011); väärin: SELECT a.asnimi FROM asiakas a WHERE EXISTS (SELECT * FROM lasku l WHERE a.astun = l.astun AND l.vuosi <> 2011); väärin: SELECT a.asnimi FROM asiakas a, lasku l WHERE a.astun = l.astun AND l.vuosi <> 2011; Vastaavat kysymykseen: Hae sellaisten asiakkaiden nimet, joita on laskutettu ainakin kerran jonakin muuna vuonna kuin 2011. ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 43

Tyypillisiä ongelmia: alikyselyn tulosten vertailu vakioon SELECT a.asnimi FROM asiakas a WHERE 2 < (SELECT COUNT(l.laskuno) FROM lasku l WHERE a.astun = l.astun); SELECT a.asnimi FROM asiakas a WHERE 10 = (SELECT COUNT(l.laskuno) FROM lasku l WHERE a.astun = l.astun); Hae sellaisten asiakkaiden nimet, joita koskee ainakin kolme laskua. Hae sellaisten asiakkaiden nimet, joita koskee täsmälleen 10 laskua. I Ei koostefunktioita WHERE-osaan. Alikyselyn tuloksia voidaan vertailla myös sarakkeeseen: SELECT tuotenimi FROM tuote WHERE ahinta > (SELECT AVG(ahinta) FROM tuote); Hae sellaisten tuotteiden nimet, joiden hinta on tuotteiden keskimääräistä hintaa korkeampi. ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 44

Tyypillisiä ongelmia: saman taulun usea läpikäynti Läpikäynnillä tarkoitetaan tässä yhteydessä taulun esittelyä hakulauseen FROM-osassa. Jos taulu halutaan tarkastaa useammin kuin kerran, on käytettävä apuna joko alikyselyiden mahdollistamia näkyvyysalueita tai useita tarkentimia yksitasoisessa ratkaisussa. SELECT asnimi, mpiiri FROM asiakas WHERE asnimi NOT LIKE 'Kajo' AND mpiiri IN (SELECT mpiiri FROM asiakas WHERE asnimi LIKE 'Kajo'); Hae niiden asiakkaiden nimet ja myyntipiirit, jotka toimivat samassa myyntipiirissä kuin Kajo. 2 asiakas asnimi Kajo Lipetti Laippa Hukari asiakas asnimi Lipetti Laippa Hukari mpiiri e k i e mpiiri k i e 4 3 asiakas asnimi Kajo Lipetti Laippa Hukari asiakas asnimi Kajo tulostaulu asnimi Hukari mpiiri e k i e mpiiri e mpiiri e 1 ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 45

Tyypillisiä ongelmia: saman taulun usea läpikäynti Hae niiden asiakkaiden nimet ja myyntipiirit, jotka toimivat samassa myyntipiirissä kuin Kajo. asiakas asnimi Kajo mpiiri e asiakas asnimi Kajo mpiiri e SELECT a1.asnimi, a1.mpiiri FROM asiakas a1, asiakas a2 WHERE a1.asnimi NOT LIKE Kajo AND a1.mpiiri = a2.mpiiri AND a2.asnimi LIKE Kajo ; SELECT a1.asnimi, a1.mpiiri FROM asiakas a1 WHERE a1.asnimi NOT LIKE Kajo AND EXISTS (SELECT * FROM asiakas a2 WHERE a1.mpiiri = a2.mpiiri AND a2.asnimi LIKE Kajo ); 2 Lipetti Laippa Hukari asiakas asnimi Lipetti Laippa Hukari k i e mpiiri k i e 3 Lipetti Laippa Hukari asiakas asnimi Kajo tulostaulu asnimi k i e mpiiri e mpiiri 1 4 Hukari e ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 46

Tyypillisiä ongelmia: jako-operaatio Jako-operaatiolle tyypillistä on tunnistaa, löytyykö liitosehdon muodostavan sarakkeen arvo liitoksen toisen puolen taulun jokaiselta riviltä. Hae sellaisten laskujen laskunumerot, jotka koskevat kaikkia tuotteita. SELECT DISTINCT lr1.laskuno FROM lasku_rivi lr1 WHERE NOT EXISTS (SELECT * FROM tuote t WHERE NOT EXISTS (SELECT * FROM lasku_rivi lr2 WHERE lr2.laskuno = lr1.laskuno AND lr2.tuotetun = t.tuotetun)); = SELECT laskuno FROM lasku_rivi WHERE tuotetun IN (SELECT tuotetun FROM tuote) GROUP BY laskuno HAVING COUNT(*) = (SELECT COUNT(*) FROM tuote); Ei ole olemassa sellaista tuotetunnusta, jota lasku ei koskisi. Laskua koskevia lasku_rivejä on yhtä monta kuin on tuotteita tuote-taulussa. ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 47

Integroivia esimerkkejä SELECT asnimi FROM asiakas WHERE asnimi NOT LIKE 'Kassakko' AND astun IN (SELECT astun FROM lasku WHERE laskuno IN (SELECT laskuno FROM lasku_rivi WHERE tuotetun IN (SELECT tuotetun FROM lasku_rivi WHERE laskuno IN (SELECT laskuno FROM lasku WHERE astun IN (SELECT astun FROM asiakas WHERE asnimi LIKE 'Kassakko') ) ) ) ); Hae sellaisten asiakkaiden nimet, joita on joskus laskutettu samasta tuotteesta kuin Kassakko-nimistä asiakasta. asiakas ( asnimi, astun ) lasku ( laskuno, astun ) lasku_rivi ( laskuno, tuotetun ) lasku_rivi ( laskuno, tuotetun ) lasku ( laskuno, astun ) asiakas ( asnimi, astun ) tarkastetaan, että nimi ei ole Kassakko tarkastetaan, että nimi on Kassakko ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 48

Integroivia esimerkkejä SELECT asnimi FROM asiakas WHERE asnimi NOT LIKE 'Kassakko' AND astun IN (SELECT astun FROM lasku WHERE laskuno IN (SELECT laskuno FROM lasku_rivi WHERE tuotetun IN (SELECT tuotetun FROM lasku_rivi WHERE laskuno IN (SELECT laskuno FROM lasku WHERE astun IN (SELECT astun FROM asiakas WHERE asnimi LIKE 'Kassakko') ) ) ) ); = Liitostapoja voidaan yhdistellä: SELECT asnimi FROM asiakas WHERE asnimi NOT LIKE 'Kassakko' AND astun IN (SELECT astun FROM lasku l1 WHERE EXISTS (SELECT * FROM lasku_rivi lr1, lasku_rivi lr2, lasku l2, asiakas a WHERE l1.laskuno = lr1.laskuno AND lr1.tuotetun = lr2.tuotetun AND lr2.laskuno = l2.laskuno AND l2.astun = a.astun AND a.asnimi LIKE Kassakko ) ); Kaikissa lauseissa on 6 taulua ja 5 liitosta. = IV Lauseessa n taulua vaatii n-1 liitosta, pl. ristitulo. SELECT DISTINCT as1.asnimi FROM asiakas as1, asiakas as2, lasku l1, lasku l2, lasku_rivi lr1, lasku_rivi lr2 WHERE as1.astun = l1.astun AND l1.laskuno = lr1.laskuno AND lr1.tuotetun = lr2.tuotetun AND lr2.laskuno = l2.laskuno AND l2.astun = as2.astun AND as1.asnimi NOT LIKE 'Kassakko' AND as2.asnimi LIKE 'Kassakko'; ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 49

Integroivia esimerkkejä Hae sellaisten tuotteiden nimet, joita on ostettu ainakin kerran vuonna 2000 mutta ei kertaakaan vuonna 2001. TUOTE tuotetun CHAR(4) tuotenimi VARCHAR(15) malli VARCHAR(10) ahinta INT vari VARCHAR(10) SELECT t.tuotenimi FROM tuote t WHERE EXISTS (SELECT * FROM lasku_rivi lr, lasku l WHERE t.tuotetun = lr.tuotetun AND lr.laskuno = l.laskuno AND l.vuosi = 2000) AND NOT EXISTS (SELECT * FROM lasku_rivi lr, lasku l WHERE t.tuotetun = lr.tuotetun AND lr.laskuno = l.laskuno AND l.vuosi = 2001); Huomaa, että molemmat alikyselyt ovat ns. saman arvoisia, ts. ne eivät ole sisäkkäin. SELECT tuotenimi FROM tuote WHERE tuotetun IN (SELECT tuotetun FROM lasku_rivi WHERE laskuno IN (SELECT laskuno FROM lasku WHERE vuosi = 2000) ) AND tuotetun NOT IN (SELECT tuotetun FROM lasku_rivi WHERE laskuno IN (SELECT laskuno FROM lasku WHERE vuosi = 2001) ); LASKU_RIVI laskuno CHAR(4) tuotetun CHAR(4) maara INT LASKU laskuno CHAR(4) vuosi INT lask_summa INT tila VARCHAR(2) astun CHAR(4) ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 50

Integroivia esimerkkejä Hae sellaisten laskujen tiedot, jotka koskevat ainakin neljää erilaista tuotetta. LASKU laskuno CHAR(4) vuosi INT lask_summa INT tila VARCHAR(2) astun CHAR(4) SELECT * FROM lasku WHERE laskuno IN (SELECT laskuno FROM lasku_rivi GROUP BY laskuno HAVING COUNT(*) > 3); = SELECT * FROM lasku l WHERE 3 < (SELECT COUNT(*) FROM lasku_rivi lr WHERE lr.laskuno = l.laskuno); LASKU_RIVI laskuno CHAR(4) tuotetun CHAR(4) maara INT Hae osastoittain tunnukset ja palkkakeskiarvot osastoilta, joissa maksimipalkka on pienempi kuin koko yrityksen työntekijöiden keskipalkka: SELECT otun, AVG(ttpalkka) FROM tyontekija GROUP BY otun HAVING MAX(ttpalkka) < (SELECT AVG(ttpalkka) FROM tyontekija); HUOM. vertailu vaatii alikyselyn! TYONTEKIJÄ tttun CHAR(4) ttnimi VARCHAR(20) ttpalkka INT otun CHAR(4) ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 51

Vastaavuudet relaatioalgebran operaatioihin 1. Projektio π saavutetaan lauseen SELECT-osalla. SELECT tuotenimi, malli ; 2. Valinta σ saavutetaan lauseen WHERE-osan ehtolausekkeilla. WHERE ahinta > 100 AND ; 3. Yhdiste saavutetaan UNION-predikaatilla. SELECT laskuno FROM lasku UNION SELECT laskuno FROM lasku_rivi; Hae laskunumerot laskuja lasku_rivi-tauluista. 4. Leikkaus ja 5. liitos saavutetaan esim. EXISTS-predikaatilla. ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 52

Vastaavuudet relaatioalgebran operaatioihin 6. Erotus saavutetaan esim. NOT EXISTS predikaatilla. 7. Jako-operaatio saavutetaan esim. NOT EXISTS predikaatilla tai koostefunktiolla. 8. Ristitulo saavutetaan joko SELECT-osan sarakelistalla ja hakemalla kahdesta taulusta ilman liitosehtoa tai CROSS JOIN predikaatilla. SELECT tuotenimi, maara FROM tuote, lasku_rivi; SELECT tuotenimi, maara FROM tuote CROSS JOIN lasku_rivi; ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 53

Muita vastaavuuksia 9. Ulkoliitos [LEFT RIGHT] OUTER JOIN SELECT DISTINCT t.tuotenimi, lr.laskuno, lr.maara FROM tuote t LEFT OUTER JOIN lasku_rivi lr ON t.tuotetun = lr.tuotetun ORDER BY t.tuotenimi DESC, lr.laskuno; Hae tuotteiden nimet ja lukumäärät, sekä kuinka paljon tuotteita on laskukohtaisesti laskutettu. Järjestä tulokset tuotenimen mukaan laskevaan järjestykseen ja edelleen laskunumeron mukaan nousevaan järjestykseen. Listaa myös ne tuotteet, joita ei ole laskutettu. 10. Luonnollinen liitos NATURAL JOIN luottaa tietokannan hyvään loogiseen suunnitteluun. Sarakkeiden nimien täytyy olla täsmälleen samat. SELECT sarakelista FROM taulu1 NATURAL JOIN taulu2; 11. Attribuuttilistan mukainen liitos samoin nimettyjen attribuuttien mukaan. SELECT sarakelista FROM taulu1 JOIN taulu2 USING (sarakelista); ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 54

TOP 5 -virheet 1. Liitosehtoja puuttuu. 2. Koostefunktio on sijoitettu lauseen WHERE-osaan. 3. Ei-ole-olemassa -tapaus on ratkaistu väärin. 4. Ryhmittely puuttuu tai on tehty väärin. 5. Kysymys on luettu huolimattomasti: sisällöllisiä ehtoja puuttuu. ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 55

Stressikäyrä Sisältörunko 1. Johdanto 2. Käsitteellinen mallintaminen 3. Relaatiomalli 4. Transformointi 5. Relaatioalgebra 6. SQL 7. Tapahtumanhallinta 8. Normalisointi 9. Tietovarastointi 10. Hajautus 11. Tietokantaparadigmat 10 9 8 7 6 5 4 3 2 1 0 Tässä 1 2 3 4 5 6 7 8 9 10 11 ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 56

Taulurivien lisääminen Taulurivi lisätään INSERT-lauseella. Sarakkeet, joihin arvoja halutaan lisätä, voidaan antaa pilkkulistalla INTO-osassa. VALUES-osan pilkkulistassa annetut arvot tallennetaan INTO-osassa esiteltyyn vastaavaan sarakkeeseen. INSERT INTO taulu [(sarake[, sarake]*)]? VALUES (arvo[, arvo]*); INSERT INTO asiakas (astun, asnimi, kaup, tyyppi, mpiiri) VALUES ('a999', 'Jokinen Ry', 'Tampere', NULL, 'i'); ASIAKAS astun CHAR(4) asnimi VARCHAR(15) kaup VARCHAR(10) tyyppi VARCHAR(10) mpiiri VARCHAR(10) 1. sarake 2. sarake 3. sarake 4. sarake 5. sarake ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 57

Taulurivien lisääminen Jos INTO-osassa ei ole annettu pilkkulistaa, VALUES-osan arvot tallennetaan niitä vastaaviin sarakkeisiin: ensimmäinen arvo ensimmäiseen sarakkeeseen jne. Jos arvoa ei anneta VALUES-osassa, annetaan oletusarvo (tavallisesti NULL). INSERT INTO asiakas VALUES ( a809, Toivakka, Helsinki, y, e ); INSERT INTO asiakas (astun, tyyppi, mpiiri) VALUES ( a810, y, e ); ASIAKAS astun CHAR(4) asnimi VARCHAR(15) kaup VARCHAR(10) tyyppi VARCHAR(10) mpiiri VARCHAR(10) 1. sarake 2. sarake 3. sarake 4. sarake 5. sarake INSERT INTO asiakas VALUES ( a811, y, e ); VÄÄRIN. VALUES-osassa on liian vähän sarakkeita. TYONTEKIJA INSERT INTO asiakas (asnimi, kaup) SELECT (ttnimi, ttkaup) FROM tyontekija WHERE ttkkpalkka > 20000; INSERT INTO asiakas (astun, kaup) VALUES ( a101, (SELECT kaup FROM asiakas WHERE astun LIKE a100 )); tttun CHAR(4) ttnimi VARCHAR(15) ttkaup VARCHAR(10) ttkkpalkka INT ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 58

Taulurivien muokkaaminen Yhden taulun rivejä muokataan UPDATE-lauseella. UPDATE taulu SET sarake = lauseke[, sarake = lauseke]* [WHERE ehtolauseke[ operaattori ehtolauseke]*]?; WHERE-osan ehtolausekkeet päättävät, mitä rivejä muokataan. Jos WHERE-osa jätetään pois, muokataan taulun kaikkia rivejä. WHERE-osa voi sisältää miten monimutkaisia ehtoja tahansa. Kaikki tuotteet eivät salli itse määrättyjen tarkentimien käyttöä UPDATE-lauseessa. Turvallisin tapa on siis käyttää taulujen nimiä tarkentimina. ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 59

Taulurivien muokkaaminen UPDATE tuote SET ahinta = ahinta * 1.15 WHERE vari LIKE harmaa ; UPDATE tuote SET ahinta = (SELECT MIN(ahinta) FROM tuote) WHERE vari IS NULL; UPDATE lasku SET tila = m WHERE EXISTS (SELECT * FROM lasku_rivi, tuote WHERE lasku.laskuno = lasku_rivi.laskuno AND lasku_rivi.tuotetun = tuote.tuotetun AND lasku.vuosi = 2015 AND tuote.tuotenimi LIKE Kellotin ); Korota harmaiden tuotteiden hintaa 15%. Muuta niiden tuotteiden, joiden väriä ei ole määritetty, hinta samaksi kuin halvimman tuotteen hinta. Vuonna 2015 myydyt Kellottimet olivat viallisia. Hyvitä asia kirjaamalla kaikki Kellottimia sisältäneet vuoden 2015 laskut maksetuiksi. TUOTE tuotetun CHAR(4) tuotenimi VARCHAR(15) malli VARCHAR(10) ahinta INT vari VARCHAR(10) LASKU_RIVI laskuno CHAR(4) tuotetun CHAR(4) maara INT LASKU laskuno CHAR(4) vuosi INT lask_summa INT tila VARCHAR(2) astun CHAR(4) ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 60

Luentotehtävä 5 MM-kisojen urheilijat palkitaan mitalien tyypin ja määrän mukaisesti seuraavan kaavan mukaan: palkkio = Σ mtyyppi * mmaara * 10 000 missä mtyyppi: 3 = kulta, 2 = hopea, 1 = pronssi. Päivitä palkkiot olettaen, että a) urheilijalla voi olla vain yhden tyyppisiä mitaleja. b) urheilijalla voi olla usean tyyppisiä mitaleja. URHEILIJA urhtun CHAR(4) urhnimi VARCHAR(20) palkkiomaara INT MITALIT urhtun CHAR(4) mtyyppi INT mmaara INT ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 61

Luentotehtävä 5: ratkaisu Päivitä palkkiot olettaen, että a) urheilijalla voi olla vain yhden tyyppisiä mitaleja. b) urheilijalla voi olla usean tyyppisiä mitaleja. UPDATE urheilija SET palkkiomaara = (SELECT mtyyppi * mmaara * 10000 FROM mitalit WHERE urheilija.urhtun = mitalit.urhtun); UPDATE urheilija SET palkkiomaara = (SELECT SUM(mtyyppi * mmaara * 10000) FROM mitalit WHERE urheilija.urhtun = mitalit.urhtun); URHEILIJA urhtun CHAR(4) urhnimi VARCHAR(20) palkkiomaara INT MITALIT urhtun CHAR(4) mtyyppi INT mmaara INT ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 62

Taulurivien poistaminen Yhden taulun rivejä poistetaan DELETE-lauseella. DELETE FROM taulu [WHERE ehtolauseke[ operaattori ehtolauseke]*]?; Ilman WHERE-osaa poistetaan kaikki taulun rivit. WHERE-osa voi sisältää miten monimutkaisia ehtoja tahansa. Kaikki tuotteet eivät salli tarkentimien käyttöä DELETE-lauseessa. Turvallisin tapa on käyttää alikyselyitä. TUOTE tuotetun CHAR(4) tuotenimi VARCHAR(15) malli VARCHAR(10) ahinta INT vari VARCHAR(10) LASKU_RIVI laskuno CHAR(4) tuotetun CHAR(4) maara INT DELETE FROM tuote WHERE ahinta < 50 AND tuotetun NOT IN (SELECT tuotetun FROM lasku_rivi); Poista ne tuotteet, joiden hinta on alle 50 euroa ja joita ei koske yksikään lasku. ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 63

4.4 DDL: rakenteen määrittäminen Yleistä DDL:stä DDL (Data Definition Language) on SQL:n alikieli tietokannan rakenteen määrittämiseen ja tietokantaobjektien (taulut, näkymät, indeksit, triggerit jne.) hallintaan. DDL:n avulla tietokantaobjekteja voidaan luoda (CREATE), muokata (ALTER) ja poistaa (DROP). ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 64

4.4 DDL: rakenteen määrittäminen Tietokantaympäristö Tietokantaympäristön yleinen, standardiin perustuva rakenne koostuu neljästä kerroksesta: Tietokantapalvelin eli tietokantainstanssi on prosessi tai prosessiperhe, joka vastaa tietokantojen ylläpitämisestä. Tietokantapalvelin sijaitsee laitteen keskusmuistissa. Tietokantapalvelin pitää yllä katalogeja, jotka sijaitsevat tavallisesti massamuistissa. Katalogit koostuvat skeemoista eli nimiavaruuksista. Jokainen katalogi sisältää lisäksi DBMS:n luoman skeeman, jossa on tietokannan järjestelmätaulut eli metadata. Skeemat sisältävät katalogin tietokantaobjektit kuten taulut ja näkymät. Tietokantapalvelin (instanssi) Katalogi Katalogi Skeema Järjestelmätaulut Skeema Skeema Järjestelmätaulut Skeema Taulu Taulu Taulu Triggeri Taulu Taulu Triggeri Taulu Skeema Taulu Taulu Taulu Taulu Taulu Taulu Skeema Taulu Taulu ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 65

4.4 DDL: rakenteen määrittäminen Tietotyypit SQL-kieli on vahvasti tyypittävä, mikä tarkoittaa, että sarakkeelle annetaan tietotyyppi silloin, kun taulu luodaan. Yleisiä, standardin mukaisia tietotyyppejä ovat mm. Tietotyyppi Selite Käyttöesimerkki Esimerkkiarvo Esimerkkisarake CHAR, CHARACTER VARCHAR, CHARACTER VARYING Määrätyn mittainen merkkijono Vaihtelevan mittainen merkkijono CHAR(11) 010230-ABCD henkilötunnus VARCHAR(20) Aatami etunimi INTEGER, INT kokonaisluku INT 2000 syntymävuosi NUMERIC (desimaali)luku NUMERIC(7,2) 12072.54 kuukausipalkka BOOLEAN totuusarvo BOOLEAN true tilaus_vahvistettu DATE päivämäärä DATE 01 Jan 2016 tilauspvm TIMESTAMP aikaleima TIMESTAMP 01/01/2016 08:01:00+02 maksuaika ARRAY lista INTEGER[7] 1, 2, 9, 12, 19, 24, 25 lottonumerot ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 66

4.4 DDL: rakenteen määrittäminen Taulujen luominen Taulu luodaan komennolla CREATE TABLE. Komennolla annetaan vähintään taulun nimi ja otsake tietotyyppeineen. Komennon yleinen syntaksi on seuraava: CREATE TABLE taulu ( sarake tietotyyppi[, sarake tietotyyppi]* ); Tavallisesti voidaan käyttää joko auki kirjoitettuja tietotyyppien nimiä tai lyhenteitä, esim. CHAR. CREATE TABLE tuote ( tuotetun CHARACTER(4), tuotenimi CHARACTER VARYING(15), malli CHARACTER VARYING(10), ahinta INTEGER, vari CHARACTER VARYING(10) ); TUOTE tuotetun CHAR(4) tuotenimi VARCHAR(15) malli VARCHAR(10) ahinta INT vari VARCHAR(10) ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 67

4.4 DDL: rakenteen määrittäminen Perusavain Taululle voidaan määrittää perusavain joko taulun luontikomennolla tai myöhemmin muokkaamalla taulua. Taulun luontikomennolla perusavaimen lisääminen muuttaa syntaksia seuraavalla tavalla: CREATE TABLE taulu ( sarake tietotyyppi [PRIMARY KEY]?[, sarake tietotyyppi]* ); CREATE TABLE tuote ( tuotetun CHAR(4) PRIMARY KEY, tuotenimi VARCHAR(15) [...] ); Tai, jos perusavain koostuu useammasta kuin yhdestä sarakkeesta: CREATE TABLE taulu ( sarake tietotyyppi[, sarake tietotyyppi]*[, PRIMARY KEY (sarake[, sarake]*)]? ); CREATE TABLE lasku_rivi ( laskuno CHAR(4), tuotetun CHAR(4), maara INT, PRIMARY KEY (laskuno, tuotetun) ); ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 68

4.4 DDL: rakenteen määrittäminen Viiteavain Viiteavain määritetään renkitaulun (viittaavan taulun) luonnin yhteydessä tai sitä myöhemmin muokkaamalla. Sarakkeiden täytyy olla samaa tietotyyppiä, merkkijonojen täytyy olla myös (maksimi)pituudeltaan samat. CREATE TABLE taulu ( sarake tietotyyppi[, sarake tietotyyppi]*[, PRIMARY KEY (sarake[, sarake]*)]?[, FOREIGN KEY (sarake[, sarake]*) REFERENCES isäntätaulu (sarake[, sarake]*)]* ); olettaen, että tuote- ja lasku-taulut on luotu aiemmin: CREATE TABLE lasku_rivi ( laskuno CHAR(4), tuotetun CHAR(4), maara INT, PRIMARY KEY (laskuno, tuotetun), FOREIGN KEY (laskuno) REFERENCES lasku (laskuno), FOREIGN KEY (tuotetun) REFERENCES tuote (tuotetun) ); ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 69

4.4 DDL: rakenteen määrittäminen Viiteavain Lisämääreillä voidaan vaikuttaa siihen, miten toimitaan, kun isäntätaulun (viitatun taulun) viitatun sarakkeessa arvoissa tapahtuu muutoksia (UPDATE) tai rivejä poistetaan (DELETE). RESTRICT estetään muutokset ja poistot viitatussa taulussa. SET NULL asetetaan tyhjäarvo viittaavan taulun vastaaville riveille. SET DEFAULT asetetaan oletusarvo viittaavan taulun vastaaville riveille. CASCADE vyörytetään viitatun taulun muutokset ja poistot viittaavaan tauluun. CREATE TABLE lasku_rivi ( laskuno CHAR(4), tuotetun CHAR(4), maara INT, PRIMARY KEY (laskuno, tuotetun), FOREIGN KEY (laskuno) REFERENCES lasku (laskuno) ON UPDATE RESTRICT ON DELETE SET NULL, FOREIGN KEY (tuotetun) REFERENCES tuote (tuotetun) ON UPDATE RESTRICT ON DELETE RESTRICT ); ITKA204 kevät 2016 Toni Taipalus Jyväskylän yliopisto 70