1. 1 (14)
Tietohallinto-osasto
Kirsti Ikonen 17.9.2020
SP/FIVA-EI RAJOITETTU
Julkinen
VASTAUKSET
EERO SILJANDER, DATA SCIENTIST, VTL, VTM, TALOUSTIEDE.
20.9.2020.
Tehtävä 1.
Suunnittele järjestelmä, joka tarjoaa loppukäyttäjälle mahdollisuuden tehdä analyysia datasta. Järjestelmän
data tulee arkistoida 10 vuoden ajalle. Analyysityövälineenä PowerBI.
Sisään tulee ftp-siirtona arkipäivisin csv-tiedostoja määriteltyyn kansioon, 50kpl, koko 1-2mb per tiedosto, klo
8-16 välillä.
Analyytikon tulee saada hyvä näkymä edellisenä päivänä tulleeseen dataan sekä historiaan 12 kuukauden ajalta.
Tietomalli tulee olla yksinkertainen, jotta loppukäyttäjän on helppo sitä ymmärtää. Kuvaa arkkitehtuuri yleisellä
tasolla, sekä mitä teknologioita käyttäisit. Vastaa myös seuraaviin kysymyksiin:
– Mitä asioita tulee ottaa huomioon tietomallia suunnitellessa?
– Mitä tarkoittaa tietokannan denormalisointi? Missä tilanteissa siitä on hyötyä?
ALUSTUS KESKUSTELUA: I DID IT
LIKE THIS BASED ON MY WORK EXPERIENCE WITH CGI, VALVIRA, TIETO.
Tämä alla kuvattu vaiheistus 1.-5. on standardia työtekniikkaani ja voidaan laittaa asetuksiini
tallennettuna. Olen tehnyt kaikkia vaiheita 1.-5. alla servereiden perustamisista SQL Server,
Azure server, AWS server Ohio US and S3 buckets and IAM role (CGI työssäni 2020), työssäni
Valviralla 2019 (SQL ja QLikview servers & Test servers), TietoEvryllä 2018. Päätyökaluni joita
olen käyttänyt DW: MS SQL SERVER MANAGEMENT STUDIO, VISUAL STUDIO, REMOTE
DESKTOP, TEAMVIEWER, VMVARE, HADOOP HORTONWORKS. BI: POWERBI, QLIKVIEW
V.12, EXCEL.
KOODAUS: T-SQL, PYTHON, R, R STUDIO, MySQL, PostgreSQL, PlusSQL.
TIETOMALLIN KUVAUS - PERUSTUU 1.VALVIRAN TYÖKOKEMUKSEENI (QLIKVIEW RAPORTOINTI, SQL
SERVERIT)
JA 2. TIETOEVRYN 3. CGI:N
DATAN SIIRTOSUUNTA VASEMMALTA OIKEALLE JA 1.-5.
Laitan yhden excel Dashboardin liitteenä. Olen itse tehnyt. Postialue data ja PAAVO-data.
(((HUOM! Varoituksen sananen alkuun: AINA ->> RAPORTEISSA JA TIETOMALLEISSA ! 1) VAROTOIMENA TESTANA
TESTISERVERILLÄ SQL/QLIK/DAX KOODIN TOIMIVUUTTA JA SITTEN TUOTANTOSERVERILLÄ JA/TAI 2) LUODAAN
VIEW/TAULU/RAPORTTI KOPIO JOKA ERISTYKSISSÄ KOODATAAN, OHJELMOIDAAN JA TESTAAN. NUMEROIDAAN
KEHITYSVERSIOT RAPORTEISTA
ts. Ei koskaan sählätä sekaisin master/user/admin-alkuperäistä versiota.)))
TEHTÄVÄ 1. VASTAUS, ANSWER LETS GO:
1. TUOTANTOSERVERIT - http/ftp ym. tiedonsiirto (csv, ht7, txt ym. Filet). Esim. Lääkärit, hoitajat
naputtelevat potilasasiakirjoja, saneluja jne. ja niistä muodostetaan tietosanoma-sähketiedosto.
2. TUOTANTOSERVERIEN IMPULSSITIEDOSTOT MUUTETAAN RAPORTOINTISERVERIN
SQL/AZURE SERVERIEN DATAKSI TÄMÄ ON ETL -prosessi - Extract, Transform, Load -prosessi joka
voi olla yksinkertaisimmillaan Excel-taulukko ( excelissä on välilehdellä sarakkeina vasemmalta oikealle ETL-
muunnos ja rivitasolla mitä kullekin muuttujalle tapahtuu vasemmalta oikealle) joka syötetään SQL-serveriin ja
muuntaa kentät/muuttujat halutunlaisiksi. Monimutkaisempi ETL-ohjelmointi voidaan tehdä SQL-koodina
lähisukulaiskoodeilla (T-SQL, MySQL, PlusSQL, PosgreSQL jne.) tai Javalla esimerkiksi.
2. 2 (14)
Tietohallinto-osasto
Kirsti Ikonen 17.9.2020
SP/FIVA-EI RAJOITETTU
Julkinen
- Kerran yössä tuotantoserveiltä siirretään datat (ht7, txt, csv ym.)
3. RAPORTOINTISERVERIT SQL, AZURE.
- Käytän SQL management Studiota asioiden ja konfiguraatioiden tekemiseen.
- Tähtimallimalli, yleisin tapa SQL taulukoiden verkoistoimiseen keskenään.
- Domestic Key - Foreign Key joka Views-näkymässä tai Table-näkymässä.
- Luodaan dataputket (data pipelines) PowerBI tai Qlikview-ohjelmiin.
- Raportit päivittyvät automaattisesti kerran yössä, kun tehdään ajastukset.
4. ANALYYTIKON VAIHE 4. POWERBI, (QLIKVIEW).
- Suunnitellaan ja luodaan POWERBI, QLIKVIEW, EXCEL-RAPORTIT linkitettynä dataputkeen (data pipeline
joka päivittyy yleensä kerran yössä, selkeä refresh näppäin raportteihin, joka varmistaa, että ollaan ajan tasalla -
>> näin siis Valvirassa ->> Refresh painike päivämäärällä ja ajalla, jos raportti oli jumittanut/bugittanut!
- Active directory (AD) administrator tai data base administrator (DBA) tai AWS servereillä käytetään IAM
admininistrator oikeuksilla annetaan oikeudet analyytikolle/asiantuntijalle oikeudet hänen toimialansa ja
toimialueensa raportteihin tai sitten vain yksittäisiin raportteihin (tein tätä Valviralla, TIETO, CGI).
Ohessa alla on kuva (lähde: Informatica blogger-kuva, google search: etl process) koko Extract,Transform,Load
(ETL-prosessista), Lähde: Informatica Tutorials, Blogger. Siinä näkyy kuinka datalähteet vasemmalla (data
sources, tuotantoserverit sanottiin TIEDOLLA, TIETO OYJ) siirretään ETL-prosessin kautta Data Warehouseen
(raportointiserverit sanottiin TIEDOLLA) ja siitä datapipelinea (dataputkea pitkin) POWERBI,QLIKVIEW,
EXCEL-ohjelmiin.
5. TIETOTURVA KAIKISSA ETL-VAIHEISSA JA SERVEREILLÄ JA TYÖASEMILLA
VARMISTETAAN AINA, VIRUSTORJUNTA/PALOMUURIT KUNNOSSA JA PÄIVITETTY, OLEN
SUORITTANUT VAHTI JA GDPR KOULUTUKSET VALVIRALLA JA SERGELILLÄ 2019-2018.
3. 3 (14)
Tietohallinto-osasto
Kirsti Ikonen 17.9.2020
SP/FIVA-EI RAJOITETTU
Julkinen
Tehtävä 2.
Aiemmin suunniteltu järjestelmä halutaan Microsoft SQL Server-alustalle.
Kirjoita auki kahden tai useamman taulun luontilauseet sisältäen sopivien analyysikäyttöön
soveltuvien indeksien ja avaimien luonnit.
Kirjoita auki vähintään yhden tietoa muokkaavan funktion (esim. aikamuodon formatointi)
luontilause
Kirjoita auki vähintään yhden tiedon hakuun käytettävän proseduurin luontilause.
o Vähintään yhden proseduurin tulee ottaa vastaan parametreja, sen tulee hyödyntää
aiemmin luotua funktiota ja yhdistää dataa vähintään kahdesta taulusta.
VASTAUS TEHTÄVÄ2:
SQL-KOODIN ESIMERKKI LÄÄKÄRIN DIABETES2 POTILAIDEN RAPORTISTA
JONKA OLEN ITSE OHJELMOINUT YHDESSÄ MAINITSEMISTANI TYÖPAIKOISTA (TOIMITAN
LISÄÄ ESIMERKKEJÄ TARVITTAESSA) Yst.terv. Eero Siljander:
WITH
Vpaine
AS
(SELECT DISTINCT Henkilotunniste , Tulos
4. 4 (14)
Tietohallinto-osasto
Kirsti Ikonen 17.9.2020
SP/FIVA-EI RAJOITETTU
Julkinen
FROM
(SELECT Henkilotunniste,
--Convert(char(10),Til.Numeerinenarvo) AS tulos,
Convert(char(10),Til.Numeerinenarvo) + Convert(char(10),Til.ToinenNumeerinenArvo) As Tulos ,
til.MittausAika,
RANK() OVER (PARTITION BY Henkilotunniste ORDER BY til.Mittausaika DESC) dest_rank
FROM core.til_tap_sisalto_view AS Til --INNER JOIN
--verenpaineet ON Til.MerkintaAvain IN (verenpaineet.VPAvain)
-- core.HenkiloHistoria_view AS heh ON Til.HenkiloAvain = heh.Avain INNER
JOIN
-- core.MerkintaHIstoria_view as Mer ON Til.MerkintaAvain = Mer.Avain --
INNER JOIN
--core.SuorittajaHistoria_view ON core.SuorittajaHistoria_view.Avain =
Til.MittaajanAvain
--INNER JOIN core.Kalenteri_view as k on k.Avain=Til.MerkintaPvmAvain
WHERE CONVERT(VARCHAR(10), Til.Mittausaika,112) between (@Loppuaika-30000) and @Loppuaika
and MerkintaAvain = 885
--Mer.Tunnus IN ('PAINE') --and heh.ikaluokkanyt>=30
) a WHERE dest_rank = 1
) ,
AHTUP
AS
(SELECT DISTINCT Henkilotunniste , Tulos
FROM
(SELECT Henkilotunniste,
--Convert(char(10),Til.Numeerinenarvo) AS tulos,
Til.Tekstiarvo As Tulos ,
til.MittausAika,
RANK() OVER (PARTITION BY Henkilotunniste ORDER BY til.Mittausaika DESC) dest_rank
FROM core.til_tap_sisalto_view AS Til --INNER JOIN
--verenpaineet ON Til.MerkintaAvain IN (verenpaineet.VPAvain)
-- core.HenkiloHistoria_view AS heh ON Til.HenkiloAvain = heh.Avain INNER
JOIN
-- core.MerkintaHIstoria_view as Mer ON Til.MerkintaAvain = Mer.Avain --
INNER JOIN
--core.SuorittajaHistoria_view ON core.SuorittajaHistoria_view.Avain =
Til.MittaajanAvain
--INNER JOIN core.Kalenteri_view as k on k.Avain=Til.MerkintaPvmAvain
WHERE CONVERT(VARCHAR(10), Til.Mittausaika,112) between (@Loppuaika-30000) and @Loppuaika
5. 5 (14)
Tietohallinto-osasto
Kirsti Ikonen 17.9.2020
SP/FIVA-EI RAJOITETTU
Julkinen
and MerkintaAvain = 264
--Mer.Tunnus IN ('AHTUP') --and heh.ikaluokkanyt>=30
) a WHERE dest_rank = 1
) ,
Paino
AS
(SELECT DISTINCT Henkilotunniste , Tulos
FROM
(SELECT Henkilotunniste,
--Convert(char(10),Til.Numeerinenarvo) AS tulos,
Til.Numeerinenarvo As Tulos ,
til.MittausAika,
RANK() OVER (PARTITION BY Henkilotunniste ORDER BY til.Mittausaika DESC) dest_rank
FROM core.til_tap_sisalto_view AS Til --INNER JOIN
--verenpaineet ON Til.MerkintaAvain IN (verenpaineet.VPAvain)
-- core.HenkiloHistoria_view AS heh ON Til.HenkiloAvain = heh.Avain INNER
JOIN
--core.MerkintaHIstoria_view as Mer ON Til.MerkintaAvain = Mer.Avain --
INNER JOIN
--core.SuorittajaHistoria_view ON core.SuorittajaHistoria_view.Avain =
Til.MittaajanAvain
--INNER JOIN core.Kalenteri_view as k on k.Avain=Til.MerkintaPvmAvain
WHERE CONVERT(VARCHAR(10), Til.Mittausaika,112) between (@Loppuaika-30000) and @Loppuaika
and MerkintaAvain = 888
--Mer.Tunnus IN ('Paino') --and heh.ikaluokkanyt>=30
) a WHERE dest_rank = 1
) ,
Pituus
AS
(SELECT DISTINCT Henkilotunniste , Tulos
FROM
(SELECT Henkilotunniste,
--Convert(char(10),Til.Numeerinenarvo) AS tulos,
Til.Numeerinenarvo As Tulos ,
til.MittausAika,
RANK() OVER (PARTITION BY Henkilotunniste ORDER BY til.Mittausaika DESC) dest_rank
6. 6 (14)
Tietohallinto-osasto
Kirsti Ikonen 17.9.2020
SP/FIVA-EI RAJOITETTU
Julkinen
FROM core.til_tap_sisalto_view AS Til --INNER JOIN
--verenpaineet ON Til.MerkintaAvain IN (verenpaineet.VPAvain)
-- core.HenkiloHistoria_view AS heh ON Til.HenkiloAvain = heh.Avain INNER
JOIN
--core.MerkintaHIstoria_view as Mer ON Til.MerkintaAvain = Mer.Avain --
INNER JOIN
--core.SuorittajaHistoria_view ON core.SuorittajaHistoria_view.Avain =
Til.MittaajanAvain
--INNER JOIN core.Kalenteri_view as k on k.Avain=Til.MerkintaPvmAvain
WHERE CONVERT(VARCHAR(10), Til.Mittausaika,112) between (@Loppuaika-30000) and @Loppuaika
and MerkintaAvain = 889
--Mer.Tunnus = ('Pituus') --and heh.ikaluokkanyt>=30
) a WHERE dest_rank = 1
) ,
Diag
AS
(
SELECT DISTINCT Henkilotunnus , Diagnoosi
FROM
(SELECT heh.Henkilotunnus,
CASE WHEN diag.Koodi1 like 'E11%' THEN 'Dg_T2D' WHEN diag.Koodi1 >= 'I10' AND diag.Koodi1 <=
'I15.9' THEN 'Dg_Verenp'
WHEN diag.Koodi1 >= 'I20' AND diag.Koodi1 <= 'I25.9' THEN 'Dg_Sepelv' WHEN diag.Koodi1 >=
'I60' AND diag.Koodi1 <= 'I69.9' THEN 'Dg_AVH'
WHEN diag.Koodi1 like 'I48%' THEN 'Dg_EV' WHEN ((diag.Koodi1 >= 'N17' AND diag.Koodi1 <=
'N19.9') OR (diag.Koodi1 >= 'I12' AND diag.Koodi1 <= 'I12.9')) THEN 'Dg_MV'
WHEN diag.Koodi1 = 'G47.3' THEN 'Dg_UA' WHEN diag.Koodi1 like 'E78%' THEN 'Dg_DL' END AS
Diagnoosi,
Potd.Kirjausaika,
RANK() OVER (PARTITION BY Henkilotunnus, Koodi1 ORDER BY Potd.Kirjausaika DESC) dest_rank
FROM core.PotilasDiagnoosi_view AS Potd INNER JOIN
core.HenkiloHistoria_view AS heh ON Potd.HenkiloAvain = heh.Avain INNER
JOIN
core.DiagnoosiHistoria_view as diag ON Potd.DiagnoosiAvain = diag.Avain
WHERE Potd.KirjausPvm <= @Loppuaika
AND (diag.Koodi1 like 'E11%')
OR (diag.Koodi1 >= 'I10' AND diag.Koodi1 <= 'I15.9')
OR (diag.Koodi1 >= 'I20' AND diag.Koodi1 <= 'I25.9')
OR (diag.Koodi1 >= 'I60' AND diag.Koodi1 <= 'I69.9')
OR (diag.Koodi1 like 'I48%')
7. 7 (14)
Tietohallinto-osasto
Kirsti Ikonen 17.9.2020
SP/FIVA-EI RAJOITETTU
Julkinen
OR ( (diag.Koodi1 >= 'N17' AND diag.Koodi1 <= 'N19.9') OR (diag.Koodi1 >= 'I12' AND
diag.Koodi1 <= 'I12.9'))
OR (diag.Koodi1 = 'G47.3')
OR (diag.Koodi1 like 'E78%')
) a WHERE dest_rank = 1
),
Ksyy
AS
(
SELECT DISTINCT HenkilotunnusHash , Käyntisyy
FROM
(SELECT HenkilotunnusHash,
CASE WHEN ksyy.KayntisyyKoodi = 'T90' THEN 'Ks_T2D' WHEN ksyy.KayntisyyKoodi >= 'K85' AND
ksyy.KayntisyyKoodi <= 'K87' THEN 'Ks_Verenp'
WHEN ksyy.KayntisyyKoodi >= 'K74' AND ksyy.KayntisyyKoodi <= 'K77' THEN 'Ks_Sepelv' WHEN
ksyy.KayntisyyKoodi >= 'K89' AND ksyy.KayntisyyKoodi <= 'K91' THEN 'Ks_AVH'
END AS Käyntisyy,
kon.TapahtumaAika,
RANK() OVER (PARTITION BY HenkilotunnusHash, KayntisyyKoodi ORDER BY kon.TapahtumaAika DESC)
dest_rank
FROM core.Kayntisyy_view AS ksyy INNER JOIN
core.Kontakti_view as kon ON kon.KontaktiTunniste = ksyy.Kontaktilinkki
WHERE kon.KayntiPvm <= @Loppuaika
AND KayntisyyKoodi = 'T90' OR (KayntisyyKoodi >= 'K85' AND KayntisyyKoodi <= 'K87')
OR (KayntisyyKoodi >= 'K74' AND KayntisyyKoodi = 'K77')
OR (KayntisyyKoodi >= 'K89' AND KayntisyyKoodi = 'K91')
) a WHERE dest_rank = 1
),
Labra
AS
(SELECT DISTINCT Henkilotunnus , Tulos, Tunnus, NaytteenOttoaikaAvain
FROM
(SELECT Henkilotunnus,
(CASE WHEN lab.NumeerinenTutkimustulos IS NULL THEN (CASE WHEN lab.SanallinenTutkimustulos =
'Yli 60' THEN 61 END) ELSE lab.NumeerinenTutkimustulos END) AS tulos,
lab.NaytteenOttoaikaAvain, tutk.TilastoitavaLyhenne AS Tunnus,
RANK() OVER (PARTITION BY Henkilotunnus, tutk.TilastoitavaLyhenne ORDER BY
lab.NaytteenottoaikaAvain DESC) dest_rank
FROM core.Vastausarkisto_view AS lab INNER JOIN
8. 8 (14)
Tietohallinto-osasto
Kirsti Ikonen 17.9.2020
SP/FIVA-EI RAJOITETTU
Julkinen
core.HenkiloHistoria_view AS heh ON lab.HenkiloAvain = heh.Avain INNER
JOIN
core.TutkimusOhjausHistoria_view as tutk ON lab.TutkimusNumerotunnusAvain
= tutk.Avain
WHERE lab.NaytteenOttoaikaAvain Between ( @Loppuaika - 30000) and @Loppuaika
--and tutk.TilastoitavaLyhenne IN ('*fP-KolLDL', '*fP-Kol-LD', 'cU-Alb-Mi','*U-Alb/Kr','*Pt-
GFRe-M','*B -Hb-A1C')
and tutk.TilastoitavaLyhenne IN ('fP-Kol-LDL', 'P -Alb','P -Krea','nU-Alb', 'U -Alb','Pt-
GFReEPI','B -HbA1c')
--and heh.ikaluokkanyt>=30
) a WHERE dest_rank = 1
)
SELECT distinct Henk.Henkilotunnus,
--core.Kontakti_view.Ikaluokka as Ika,
Henk.Sukupuoli, Henk.SyntymaPaiva ,
Vpaine.Tulos AS verenpaine,
AHTUP.Tulos AS AHTUP,
Paino.Tulos AS Paino,
Pituus.Tulos AS Pituus,
Diag.Diagnoosi,
Ksyy.Käyntisyy,
Labra.Tunnus AS LabraTunnus,
Labra.tulos AS LabraTulos,
Labra.NaytteenOttoaikaAvain AS LabraAika
,core.YksikkoHistoria_view.YksikkoLyhenne,
core.SuorittajaHistoria_view.Kayttajatunnus,
core.Kontakti_view.KuntaKoodi,
core.kontakti_view.Kontaktilaji
FROM core.Kontakti_view
inner join core.HenkiloHistoria_view as Henk ON core.Kontakti_view.HenkiloAvain = henk.Avain
INNER JOIN
core.SuorittajaHistoria_view ON core.SuorittajaHistoria_view.Avain =
core.Kontakti_view.SuorittajaAvain
inner join core.YksikkoHistoria_view on
core.YksikkoHistoria_view.Avain=core.Kontakti_view.PaikkaAvain
LEFT OUTER JOIN Vpaine ON VPaine.HenkiloTunniste = hEnk.HenkilotunnusHash
LEFT OUTER JOIN AHTUP ON AHTUP.HenkiloTunniste = hEnk.HenkilotunnusHash
9. 9 (14)
Tietohallinto-osasto
Kirsti Ikonen 17.9.2020
SP/FIVA-EI RAJOITETTU
Julkinen
LEFT OUTER JOIN Paino ON Paino.HenkiloTunniste = hEnk.HenkilotunnusHash
LEFT OUTER JOIN Pituus ON Pituus.HenkiloTunniste = hEnk.HenkilotunnusHash
LEFT OUTER JOIN Diag ON Diag.Henkilotunnus = Henk.Henkilotunnus
LEFT JOIN Ksyy ON ksyy.HenkilotunnusHash = Henk.HenkilotunnusHash
LEFT OUTER JOIN Labra ON Labra.Henkilotunnus = Henk.Henkilotunnus
WHERE core.Kontakti_view.Kayntipvm BETWEEN @Alkuaika AND @Loppuaika
--and core.YksikkoHistoria_view.YksikkoLyhenne IN (@YksikönLyhenne)
-- AND core.SuorittajaHistoria_view.Kayttajatunnus IN (@Käyttäjätunnus)
--AND core.kontakti_view.Ika>=30
--and core.kontakti_view.Kontaktilaji In (@Kontaktilaji)
AND (Diag.Diagnoosi = @ID1__koodi OR ksyy.Käyntisyy = @Kayntisyy )
Tehtävä 3.
Kuvaa lyhyesti mitä tässä tapahtuu.
Miten mahdollisesti parantaisit?
Lähden purkamaan auki koodia: tässä luodaan näkymä (siis taulu, jossa muuttujia eli sarakkeita
(verenpaine, kolestroli, sokeriarvo, jne) ja rivejä eli tietosyötteitä esim. Potilaan1, potilaan2, potilaan3
tiedot (sarake)muuttujien (vpaine=verenpaine, kolestroli, sokeriarvo, diagnoosi) osalta.
VASTAUS TEHTÄVÄ3: Database johon näkymä eli VIEW luodaan CREATE VIEW
komennolla....Muuttujat jotka siihen valitaan ovat:
MUTTA SIIS
PAREMPI ETTÄ KOMMENTOIN KOODIIN ALLE
YST.TERV EERO SILJANDER.
CREATE VIEW [dbo].[vwUnitLink] - tässä luodaan VIEW eli näkymä nimeltä [dbo].[vwUnitLink]
AS
WITH CTE - tässä luodaan alikomentona CTE niminen näkymä eli view
- AS (
SELECT - standardi SQL valintalauseke ja lähes aina aloittaa komentojen syötön -
UNIT.COPAID, - valitaan UNIT viewsta COPAID niminen muuttuja
10. 10 (14)
Tietohallinto-osasto
Kirsti Ikonen 17.9.2020
SP/FIVA-EI RAJOITETTU
Julkinen
UNIT.COPAID AS ParentID, -valitaan COPAID muuttuja UNIT viewsta ja nimetään se
ParentID muuttujaksi
0 AS [Level] - ilmoitetaan nollamuuttuja nimellä [Level] eli sarake nollia.
FROM dbo.Unit AS UNIT - määrätään ohjelmalle että poimitaan täältä dbo.Unit ja samalla
nimetään uudelleen se UNIT viewksi.
LEFT OUTER JOIN dbo.UnitLink AS LINK ON LINK.LinkedCOPAID = UNIT.COPAID
- VIEWEJÄ YHDISTETÄÄN LEFT OUTER JOIN KOMENNOLLA, ts. taulu dbo.UnitLink AS LINK nimetään LINK
- LINK JA UNIT NÄKYMÄT YHDISTETÄÄN LEFT OUTER JOIN KOMENNOLLA
- domestic ja foreign keys avaimet ovat 1) LINK.LinkedCOPAID ja 2) UNIT.COPAID
-
WHERE LINK.Id IS NULL - tässä valitaan KOKO LINK VIEWSTÄ PUUTTUVAT TIEDOT IS NULL -> ts.
sellaiset Id muuttujan arvot jotka ovat puuttuvia tietoja (ei pidä sekoittaa nollaan numerona).
UNION ALL - UNION ALL lauseke yhdistää kaikki rivit keskenään (raskaahko prosessi, yleensä
JOIN käytösssä varsinkin LEFT JOIN ja INNER JOIN. Nyt sensijaan UNION poimii kaikki datat, eli
no hätä, ei hätää, kaikki data poimitaan mukaan uuteen muodostettavaa näkymään, mitään ei
pudoteta kuten voi käydä esim INNER JOIN lauseella.
SELECT - valitaan muuttujat lauseke
CTE.COPAID, - valitaan muuttuja COPAID viewsta CTE
LINK.LinkedCOPAID AS ParentID, -valitaan muuttuja LinkedCOPAID viewsta LINK ja
nimetään uudelleen nimellä ParentID
1 + CTE.[Level] AS [Level] -valitaan muuttuja [level] views/tablesta CTE ja
lisätään siihen 1 ja nimetään uudelleen muuttujaksi [level]
FROM dbo.UnitLink AS LINK - haetaan databasesta dbo.UnitLink ja nimetään nimellä LINK
INNER JOIN CTE AS CTE ON CTE.ParentID = LINK.COPAID - yhdistetäään inner joinilla käyttäen
domestic ja foreign avaimia.
)
SELECT ISNULL(CTE.COPAID,0) AS COPAID , - tässä valitaan puuttuvia havaintoja IS NULL
näkymästä viewsta CTE ja sen muuttujasta COPAID
TAI mikäli näin ei ole niin ASETETAAN NUMEERINEN ARVO NOLLA=0.
Käytännössä saadaan tuloksena puuttuvia havaintoja ja nollia - FILTERÖIDÄÄN ESIIN
ONGELMAKOHTIA NÄKYMÄSSÄ ! SIIS PUUTTUVIA HAVAINTOJA MUUTTUJAN MUODOSSA !
ISNULL(CTE.ParentID,0) AS LinkedCOPAID ,
- tässä valitaan puuttuvia havaintoja IS NULL näkymästä viewsta CTE ja sen muuttujasta
ParentID
TAI mikäli näin ei ole niin ASETETAAN NUMEERINEN ARVO NOLLA=0.
Käytännössä saadaan tuloksena puuttuvia havaintoja ja nollia - FILTERÖIDÄÄN ESIIN
ONGELMAKOHTIA NÄKYMÄSSÄ ! SIIS PUUTTUVIA HAVAINTOJA MUUTTUJAN MUODOSSA !
CTE.[Level] FROM CTE
- VALITAAN VIELÄ: CTE näkymästä eli viewstä [Level] niminen muuttuja. CTE. Etuliite viittaa
tähän näkymään muuttujan edessä.
11. 11 (14)
Tietohallinto-osasto
Kirsti Ikonen 17.9.2020
SP/FIVA-EI RAJOITETTU
Julkinen
GO - Proseduuri laitetaan käyntiin !
EERO SILJANDER, ANALYYSI JA YHTEENVETO YLLÄ KOMMENTOIMANI KOODAUKSEN PERUSTEELLA:
1) Tässä jahdataan ja metsästetään puuttuvia havaintoja (NULL) eri NÄKYMISTÄ (VIEWS). Datan
puhistusta ja siivous, siitä on tässä työssä kyse. Joko NULL (puuttuva havainto) tai nolla
numeerisena lukuna (jos aitoa dataa löytyy, siis maskimuuttuja) muodostettaviin muuttujiin
tehdään tässä tehtävässä 3.
2) Ja muodostetaan joko IS NULL=puuttuva havainto tai nolla numeerisena arvona näihin
Haluttuihin muuttujiin kuten COPAID, LinkedCOPAID ! Datan siivoamista ! Muodostetaan uusi
NÄKYMÄ - VIEW alkukomennolla joka kokoaa nämä datan siivouksen tulokset yhteen.
Käytetään LEFT OUTER JOIN ja UNION ALL viewsien yhdistämiskomentoja lähde-VIEW yhdistelyssä!
3) Tässä NULL- puuttuvien havaintojen jahdissa ja metsästyksessä käytetään useita eri view-
lähteitä kuten nimettynä UNIT view siis dbo.Unit, ja toisaalta dbo.UnitLink nimettynä LINK ja
kootaan löydettyä dataa väliproseduurina CTE-nimiseen aliproseduurin viewsiin (välituote).
sitten
KAIKKIEN PUUTTUVIEN HAVAINTOJEN (NULL) VIEW:T YHTEEN
Saadaan
LOPPUTULOKSENA CTE-aliproseduurin luomisesta luodaan lopulta viewsien yhdistelyjen ja
muuttujamuunnosten jälkeen -> koodin 1.rivin alun CREATE VIEW komennolla uusi VIEW nimeltä:
[dbo].[vwUnitLink]
Lisätiedot ja kätevä koodarin pikku apuri: W3-SCHOOL:
Suosittelen: https://www.w3schools.com/
https://www.w3schools.com/sql/sql_null_values.asp
1 SQL NULL Values
❮ PreviousNext ❯
1.1 What is a NULL Value?
A field with a NULL value is a field with no value.
If a field in a table is optional, it is possible to insert a new record or update a record without adding a value
to this field. Then, the field will be saved with a NULL value.
12. 12 (14)
Tietohallinto-osasto
Kirsti Ikonen 17.9.2020
SP/FIVA-EI RAJOITETTU
Julkinen
Note: A NULL value is different from a zero value or a field that contains spaces. A field with a NULL value is one
that has been left blank during record creation!
1.2 How to Test for NULL Values?
It is not possible to test for NULL values with comparison operators, such as =, <, or <>.
We will have to use the IS NULL and IS NOT NULL operators instead.
1.2.1 IS NULL Syntax
SELECT column_names
FROM table_name
WHERE column_name IS NULL;
1.2.2 IS NOT NULL Syntax
SELECT column_names
FROM table_name
WHERE column_name IS NOT NULL;
1.3 Demo Database
Below is a selection from the "Customers" table in the Northwind sample database:
CustomerID CustomerName ContactName Address City PostalCode
1 Alfreds Futterkiste Maria Anders Obere Str. 57 Berlin 12209
2 Ana Trujillo
Emparedados y helados
Ana Trujillo Avda. de la
Constitución 2222
México
D.F.
05021
3 Antonio Moreno
Taquería
Antonio
Moreno
Mataderos 2312 México
D.F.
05023
13. 13 (14)
Tietohallinto-osasto
Kirsti Ikonen 17.9.2020
SP/FIVA-EI RAJOITETTU
Julkinen
4 Around the Horn Thomas Hardy 120 Hanover Sq. London WA1 1DP
5 Berglunds snabbköp Christina
Berglund
Berguvsvägen 8 Luleå S-958 22
1.4 The IS NULL Operator
The IS NULL operator is used to test for empty values (NULL values).
The following SQL lists all customers with a NULL value in the "Address" field:
1.4.1 Example
SELECT CustomerName, ContactName, Address
FROM Customers
WHERE Address IS NULL;
Try it Yourself »
Tip: Always use IS NULL to look for NULL values.
1.5 The IS NOT NULL Operator
The IS NOT NULL operator is used to test for non-empty values (NOT NULL values).
The following SQL lists all customers with a value in the "Address" field:
1.5.1 Example
14. 14 (14)
Tietohallinto-osasto
Kirsti Ikonen 17.9.2020
SP/FIVA-EI RAJOITETTU
Julkinen
SELECT CustomerName, ContactName, Address
FROM Customers
WHERE Address IS NOT NULL;
Try it Yourself »