sql ja COALESCE function käyttö

Viestiketju alueella 'Ohjelmointi' , aloittaja Hessu007, 19.11.2019.

NOSTOJA MUROPAKETIN SISÄLLÖSTÄ
  1. Hessu007

    Rekisteröitynyt:
    19.11.2019
    Viestejä:
    3
    Tervem voiko joku guru antaa ohjeistuksen miten san toiminaan kyseisen sql haun.

    KOODI ON TÄMÄ:

    SELECT kirjailija.etunimi AS "etunimi", kirjailija.sukunimi AS "sukunimi", count(*)AS "Kirjoitettuja kirjoja"
    FROM kirjailija
    LEFT OUTER JOIN kirja ON kirjailija.tekijaid = kirja.tekijaid
    GROUP BY kirjailija.sukunimi, kirjailija.etunimi
    ORDER BY kirjailija.sukunimi, kirjailija.etunimi;

    TULOS TÄMÄ:
    etunimi sukunimi Kirjoitettuja kirjoja
    Maarit Helkala 3
    Heikki Hilppala 2
    Kaisa Nyströmberg 1
    Heikki Turkunen 1
    Aatu Vilperi 1
    Eero Vilperi 2

    PITÄISI OLLA TÄMÄ:
    etunimi sukunimi Kirjoitettuja kirjoja
    Maarit Helkala 3
    Heikki Hilppala 2
    Kaisa Nyströmberg 1
    Heikki Turkunen 1
    Aatu Vilperi 0
    Eero Vilperi 2

    ONGELMA: nornmaali COUNT jättää NULL pois automaattisesti - eli listaan pitää saada tuo Aatu Vilperi 0 ja 0 mukaan. Eikös paras vaihtoehto oli COALESCE-function, mutta miten sen saa toimimaan tuossa.

    Kiitos avusta
     
  2. telcoM

    Rekisteröitynyt:
    27.08.2015
    Viestejä:
    740
    (Haistan kotiläksyn, joten ei ihan valmista ratkaisua...)

    Huomaa että nyt et ole tekemässä hakua pelkästään yhdestä taulusta "kirjailija" vaan kahden taulun yhdistelmästä "kirjailija LEFT OUTER JOIN kirja ON kirjailija.tekijaid = kirja.tekijaid". Eli voit tehdä ehtoja myös kirja-taulusta tulevien kenttien perusteella.

    Left outer join tuo tulosjoukkoon kaikki kirjailijat riippumatta siitä oliko heillä kirjoja vai ei. Jos lasket tulosjoukosta kaikki rivit per kirjailija ( count(*) ... group by ... ), tulos menee väärin niiden kirjailijoiden kohdalla jotka eivät ole kirjoittaneet mitään. Etunimi ja sukunimihän eivät ole NULLeja, koska kirjailija on kuitenkin olemassa!

    Mieti millainen rivi tulee left outer joinin tulokseksi kirjailijalle joka ei ole vielä kirjoittanut mitään, ja sen perusteella laita countille ehto joka jättää laskematta sellaiset rivit.
     
  3. Hessu007

    Rekisteröitynyt:
    19.11.2019
    Viestejä:
    3
    Kiitos, kyseessä on vanha tehtävä, joka jäi vaivaamaan koska en päässyt siinä ns"maaliin. Eli olet siinö mielessä oikeassa, mutta enää tässä vaihessa ei vaikuta opintoihin millää muotoa- vain oman oppimisen kannalta.

    Tuohon vastaukseen : alkuperöinenv ersio oli count(kirjat.kirjaid) as..... joten hakee kirjaid puolelta ja mukaan tulee listalle ottaa myös ne , joilla on tyhjää- ei siis jättää pois. eikös oikea function tuohon ole COALESCEm jolla saan tyhjälle paikalle 0 mukaan, kuten oikeassa vastauksessa? ainut vaan on, että en saa tuota COALESCE toimimaan tuon kirja.kirjaid taulut kanssa.
    Siksi joku järkevä esimerkki voisi viedä ns. oppimiskokelusta eteenpäin.
     
  4. Chris Toffer

    Rekisteröitynyt:
    18.11.2010
    Viestejä:
    40
    Tämä ei liity suoraan kysymykseen, mutta jos on samaniminen kaima kirjailija, niin tulokset tulee näiden suhteen satunnaisessa järjestyksessä, ja se on huono (esim replikointi, verifiointi). Siksi sorttauksen viimeinen kolumni pitäisi olla pää-avain, jolloin tulos on aina deterministinen.

    Eli ORDER BY kirjailija.sukunimi, kirjailija.etunimi, kirjailija.tekijaid;
     
  5. telcoM

    Rekisteröitynyt:
    27.08.2015
    Viestejä:
    740
    COUNT(*) laskee tulosjoukon rivejä, GROUP BY:llä täydennettynä kunkin ryhmän rivejä. Ja sanoit itsekin että se ei laske NULLeja mukaan.

    Nyt kun sinulla on SELECT kirjailija.etunimi AS "etunimi", kirjailija.sukunimi AS "sukunimi", count(*)AS "Kirjoitettuja kirjoja",
    silloin Aatu Vilperin ryhmän kohdalla LEFT OUTER JOINin tulosjoukossa on yksi rivi jossa on:
    - kirjailija.etunimi = Aatu
    - kirjailija.sukunimi = Vilperi
    - kirjailija.tekijaid = <jotain>
    - kirjat.kirjaid = NULL
    - kirjat.tekijaid = NULL
    - kirjat.<ihanmitävaan> = NULL

    Eli COUNT(*) tuumaa että tuossahan on yksi rivi jossa selvästi on ei-NULL sisältöä, eli "Kirjoitettuja kirjoja" -kentän arvoksi tulee 1. Tästä tulee vastaukseen rivi "Aatu Vilperi 1", kun piti olla "Aatu Vilperi 0".

    Jos tuossa COUNT(*) paikalla olisikin COUNT(kirjat.kirjaid), silloin COUNT laskee pelkästään tuon yhden kentän NULLista poikkeavia arvoja JOINista poimitun ryhmän sisällä... ja jos niitä ei ole, COUNTin arvoksi tulee 0. SELECT sitten poimii tuosta tulosjoukosta (ei siis COUNTin vaan JOINin tuloksesta, GROUP BY:n mukaisesti) lopulliseen tulosteeseen etunimen, sukunimen ja COUNTin tuloksen... joka siis oli 0.

    Toisin sanoen, näyttää siltä että ajattelet tuota ikäänkuin COUNT() olisi jotenkin laitettu lisäehdoksi tulostettavien rivien valintaan (SELECT .... WHERE COUNT(kirjat.kirjaid) <on jotain> ...) mutta siitähän ei ole kysymys kun COUNT() vain luetellaan lopulliseen tulosteeseen haluttujen kenttien joukossa.
     

Jaa tämä sivu

Alibi
Anna
Deko
Dome
Erä
Hymy
Kaksplus
Kippari
Kotilääkäri
Kotiliesi
Koululainen
Ruoka.fi
Parnasso
Seura
Suomen Kuvalehti
TM Rakennusmaailma
Tekniikan Maailma
Vauhdin Maailma
Golfpiste
Vene
Nettiauto
Ampparit
Plaza
Muropaketti