Frisbeegolf-forum.fi

Author Topic: Apua tilastointiin eli kimurantti SQL kysely - luvassa palkinto  (Read 19001 times)

Offline DGS Ylläpito

  • Tomoottajat
  • Täysjäsen
  • *
  • Posts: 120
    • View Profile
Hei,

Nyt olisi hyvä paikka osoittaa kyvykkyytensä SQL kyselyiden tekijänä, sillä kunnollinen "personal best" tyyppinen top-listaus pitäisi saada takaisin käyttöön. Ennen viimeisintä isompaa versiopäivitystä semmoinen siis oli käytössä, mutta se näytti väyläkohtaiset tulokset väärin, joten otin sen kokonaan pois. Noh, mielenkiintoinen tilasto se kuitenkin olisi, joten pyydän nyt apua sopivan kyselyn luomisessa.

Eli siis liitteenä on esimerkkidataa yhdelle radalle, josta halutaan saada top5 listaus siten, että myös väyläkohtaiset luvut ovat oikein ja että yhdeltä käyttäjältä mukana vain yksi tulos.

Tarkempina vaatimuksina siis:
- yhdeltä käyttäjältä vain yksi tulos mukaan listaan
- tämä yksi tulos luonnollisesti se paras
- jos samaa tulosta on heitetty monta kertaa, niin ensin heitetty näytetään ensin
- jos sama pelaaja on heittänyt saman tuloksen monta kertaa, niin ensimmäisen tiedot listalle (siis päiväys ja väyläkohtaiset heitot ensimmäisenä heitetyn kierroksen mukaan)
- kyselyn luonnissa on hyvä huomioida MySQL kannan rajoitteet
- taulun nimi olkoon dgs_tulos ja sarakkeet liitteen mukaisesti
- samassa taulussa myös muiden ratojen tulokset, joten rata_id pitää olla mukana kyselyssä, vaikka esimerkkiaineistossa onkin vain yhden radan tuloksia (ehkä teen toisen aineiston, jossa useamman)

Ensimmäisenä toimivan ja testatun kyselyn tuottanut saa palkinnoksi DGS Pohjolan isäntä -kiekon. Ehdotukset kyselystä voi lähettää joko tähän ketjuun vastauksena tai sähköpostilla osoitteeseen admin@discgolfscores.net. Sähköpostin otsikoksi voisi laittaa "DGS Top 5 kysely".

Terveisin,
--Mikko, DGS ylläpito

[Edit] Liitteen lisääminen ei jostain syystä onnistunut, joten tulostaulukko löytyy täältä.

[Edit2] Lisätty vaatimuksiin radan huomiointi.
« Last Edit: 27.08.12 - klo:22:44 by DGS Ylläpito »

Offline tumi

  • Konkari
  • *****
  • Posts: 1 885
  • McPathetic
    • View Profile
  • Oikea nimi: Tuomo Tanskanen
  • Seura: KFG Karkkila / NFS Nummela
Importtasin ton Sqliteen, siellä näyttäis toimivan:

SELECT *,MIN(total) as top_total FROM DGS_Tulokset_Top5 WHERE rata_id=<id> GROUP BY user_id ORDER BY top_total, date

Offline gummi

  • Seniori
  • ****
  • Posts: 352
    • View Profile
  • Oikea nimi: Tomi
  • Seura: Disc Golf Vikings
Joo tumi toi nimenomaan näyttäisi toimivan. :) Tossa sun kyselyssä toi MIN palauttaa vain sen total sarakkeen minimin - muut sarakkeet näytetään sen ekan/vikan rivin mukaan mikä tohon jää tosta group by:stä.

Mä yritin tätä kans eilen hetken pähkäillä ja eihän tuo ihan yksinkertainen query ole. Tässä oma yritykseni - en tiedä onko tämäkään ihan täysin speksin mukainen vielä.

SELECT t1.*
FROM scores t1
LEFT JOIN scores t2
ON t2.user_id = t1.user_id
  AND t2.par_total < t1.par_total
WHERE t1.course_id = <course-id>
GROUP BY t1.user_id, t1.par_total
HAVING COUNT(DISTINCT t2.par_total) < 1
ORDER BY t1.par_total ASC, t1.date DESC
LIMIT 5
All work and no DiscGolf makes anybody a sad boy/girl...

Offline gummi

  • Seniori
  • ****
  • Posts: 352
    • View Profile
  • Oikea nimi: Tomi
  • Seura: Disc Golf Vikings

SELECT *
FROM
  (
    SELECT t1.*
    FROM dgs_tulos t1
    LEFT JOIN dgs_tulos t2
    ON t2.user_id = t1.user_id
      AND t2.par_total < t1.par_total
    WHERE t1.course_vid = <course-id>
    GROUP BY t1.id
    HAVING COUNT(DISTINCT t2.id) < 1
    ORDER BY t1.par_total ASC, t1.date DESC
  )
GROUP BY user_id
ORDER BY par_total ASC


Toi ehkä saattaa toimia. Ulompi kysely vain poistaa duplikaatit & järjestelee listan, sisempi etsii käyttäjien parhaat tulokset. Date kentän järjestely riippuu hieman miten kanta on toteutettu mutta ehkä tuo toimii...
All work and no DiscGolf makes anybody a sad boy/girl...

Offline DGS Ylläpito

  • Tomoottajat
  • Täysjäsen
  • *
  • Posts: 120
    • View Profile
Nyt on testattu tähän asti ehdotettuja kyselyitä ja kuten gummi kirjoittikin, ei tumin vastaus täytä vaatimuksia. Toisaalta gummin ehdotus ainakin ensimmäisen testin jälkeen tuotti oikean tuloksen.

Näin ollen enää ei kannata lähettää uusia ehdotuksia ennen kuin gummin vastaus on kunnolla testattu ja todettu se joko toimivaksi tai joiltain osin puutteelliseksi. Tämän vahvistamiseen saattaa mennä päivä jos toinenkin, joten pyydän kärsivällisyyttä.

Offline deiga

  • Tulokas
  • *
  • Posts: 1
    • View Profile
  • Oikea nimi: Timo Sand
Tämän kyselyn hyödyntäminen suoraan on ainakin huono idea, sillä alikyselyt ovat melko hitaita verrattuna joineihin.


SELECT *
FROM
  (
    SELECT t1.*
    FROM dgs_tulos t1
    LEFT JOIN dgs_tulos t2
    ON t2.user_id = t1.user_id
      AND t2.par_total < t1.par_total
    WHERE t1.course_vid = <course-id>
    GROUP BY t1.id
    HAVING COUNT(DISTINCT t2.id) < 1
    ORDER BY t1.par_total ASC, t1.date DESC
  )
GROUP BY user_id
ORDER BY par_total ASC


Toi ehkä saattaa toimia. Ulompi kysely vain poistaa duplikaatit & järjestelee listan, sisempi etsii käyttäjien parhaat tulokset. Date kentän järjestely riippuu hieman miten kanta on toteutettu mutta ehkä tuo toimii...

Offline tumi

  • Konkari
  • *****
  • Posts: 1 885
  • McPathetic
    • View Profile
  • Oikea nimi: Tuomo Tanskanen
  • Seura: KFG Karkkila / NFS Nummela
Semmonen mutu itsellä tässä keississä, ettei välttis kannata tehdä monimutkaista ja hidasta Sql-kyselyä kun yksinkertaisella kyselyllä ja postprocessingilla voi päästä nopeampaan ja helpompaan ratkaisuun?

Offline gummi

  • Seniori
  • ****
  • Posts: 352
    • View Profile
  • Oikea nimi: Tomi
  • Seura: Disc Golf Vikings
Joo joineja ja alikyselyitä on hyvä välttää mutta jos niitä ei saisi harkitusti käyttää niin koko SQLn vois vaihtaa sit vaikka key-value storeksi. Mutta ei mennä nyt siihen. :)
DGS on kuitenkin varmaankin yli 95/5 read/write joten en näe mitään syytä miksi tuollaista hieman hitaampaa kyselyä ei voisi käyttää kunhan muistaa cachettaa tulokset fiksusti. Eikä tuo nyt oikeasti niin kovin monimutkainen/kallis kysely vielä ole...
All work and no DiscGolf makes anybody a sad boy/girl...