30.1.2017

SQL/Funktiot

Koostefunktiot



SELECT COUNT(*) AS lkm
FROM henkilo;


Koostefunktiot



SELECT COUNT(tutkinto) AS lkm
FROM henkilo;
=> NULL-arvoja ei lasketa!


Koostefunktioiden käyttö




Haetaan suurin ja pienin hinta:
SELECT MAX(hinta), MIN(hinta)
FROM tuote;


Haetaan myyjät, joiden myymien tuotteiden hinta yhteensä on yli 5000:
SELECT myyja, SUM(hinta) -- tuotteiden hintojen summa
FROM tuote
GROUP BY myyja -- ryhmittely myyjän mukaan
HAVING SUM(hinta) > 5000;

SELECT COUNT(DISTINCT city) -- monestako kaupungista
FROM authors; -- on kirjailijoita

Koostefunktioiden käyttö



Haetaan projektien yhteenlasketut tunnit:

SELECT ptun, SUM(tunnit)
FROM proj_henk GROUP BY ptun;

Monessako kaupungissa projekteja?:

SELECT COUNT(DISTINCT sijainti) FROM projekti;


Ryhmittely - Group By




Haetaan kunkin myyjän tuotteiden hintojen keskiarvo:

SELECT myyja, AVG(hinta)
FROM tuote
GROUP BY myyja;

Kunkin myyjän myymien tuotteiden määrä:

SELECT myyja, COUNT(myyja)
FROM tuote
GROUP BY myyja;

Ryhmittely - Group By



Haetaan projektien keskimääräiset tunnit:

SELECT ptun, AVG(tunnit) FROM proj_henk
GROUP BY ptun;

Akateeminen esimerkki:

SELECT ptun, AVG(tunnit) FROM proj_henk
GROUP BY htun;
=> Ei toimi järkevästi, ptun pitää olla GROUP BY -osassa!

Testaa vaikka seuraavien lisäysten jälkeen:

INSERT INTO henkilo VALUES (6666, 'Rantala', 'Ari',
'TAMPERE', 'FK', 6666.66, 66,now(),4);

INSERT INTO proj_henk
VALUES ('P4', 6666, 666,666);

Ryhmittely - Having



SELECT myyja, COUNT(*) -- myös NULL kelpaa
FROM tuote
WHERE tuoteHinta > 100
GROUP BY myyja -- hae myyjät joilla
HAVING COUNT(*) >2; -- vähintään 3 tuotetta


Merkkijonofunktioita



Merkkitiedon käsittely

Standardissa merkkijono saadaan funktiolla
SUBSTRING(mjono FROM mista FOR pituus);

-- Esim:
SELECT sukunimi, ',', SUBSTRING(etunimi FROM 1 FOR 1), '.'
FROM henkilo
Monissa tuotteissa on kuitenkin SUBSTR-funktio:
SUBSTR(mjono,mista,mihin);

-- Esim:

SELECT sukunimi, ', ', SUBSTR(etunimi,1,1), '.'
FROM henkilo;
===> Tuloksena lista:

Aaltonen, M.
Bergman, S.
jne.

Muita merkkijonofunktioita:

CHAR_LENGTH    -- merkkien määrä (Oraclessa LENGTH)
UPPER(nimi) -- merkit isoiksi (Accessissa UCase)
LOWER(nimi) -- merkit pieniksi (Accessissa LCase)
LEFT(nimi, n) -- merkkijono vasemmalta (n merkkiä)
RIGHT(nimi, n) -- merkkijono oikealta (n merkkiä)

Merkkijonofunktioita



SELECT snimi,',', SUBSTRING( enimi FROM 1 FOR 3),'.' FROM henkilo;
SELECT snimi,',', SUBSTR( enimi,1,3),'.' FROM henkilo;


SELECT snimi, char_length(snimi) AS 'Sukunimen pituus' FROM henkilo;


-- Varman päälle:
SELECT * FROM projekti WHERE lower(sijainti) = 'turku';
SELECT LEFT(enimi,3) FROM henkilo;

Vielä merkkijonojen käsittelystä



Merkkijonojen yhdistäminen/liittäminen (konkatenointi)

SELECT sukunimi || ',' || etunimi AS Nimi
FROM henkilo


Merkkijonoesimerkkejä



MySQL:
SELECT concat(enimi, ' ', snimi) AS Kokonimi FROM henkilo;


SELECT concat(LPAD(enimi,10,'-'), ' lemppari ', snimi) AS Kokonimi
FROM henkilo;

SELECT CAST(pvm as Date) AS PAIVAMAARA FROM henkilo;


SELECT snimi, enimi, CAST(veropros AS DECIMAL(5,2)) as vpros
FROM henkilo;

SELECT snimi, enimi, DATE_FORMAT(pvm, '%d.%m.%Y %H:%i:%s')
FROM henkilo ORDER BY pvm DESC; -- pvm muotoilu, uusin ensin.)


Muita funktioita



SELECT ROUND(palkka*1.1, 0) AS palkankorotus
FROM henkilo;

COALESCE(sarake, 0);


SQL:2003-standardin uusia funktioita





CASE-lause



SELECT tuote_nimi,
CASE
WHEN hinta < 100 THEN 'edullinen'
ELSE 'laatutavara'
END AS luokitus
FROM tuote


Päivämääräjuttuja



Kokeile:

SELECT CURRENT_DATE; SELECT CURDATE(); SELECT now();


SELECT YEAR(pvm) as vuosi,MONTH(pvm) as kk, DAY(pvm) AS paiva
FROM henkilo;

Päivien ero päivinä:

DATEDIFF(CURRENT_DATE, pvm) AS eropaivia







Luku on kooste Ari Hovin kirjasta, Jouni Huotarin materiaalista ja Ari Rantalan täydennyksistä.