7 edellisen päivänpäivämäärät, jotka eivät ole tietokannassa

Aabo___

Hei

Osaisiko joku neuvoa, onko edes teoriassa mahdollista luoda SQL-kysely (MySQL), joka hakisi 7 edellisen päivien päivämäärät (esim. 2008-01-18 2008-01-17 ...) Mutta päivämäärä ei olisi hakutuloksessa, jos kyseinen päivä jo löytyy tietokannasta (pvm)

7

701

    Vastaukset

    Anonyymi (Kirjaudu / Rekisteröidy)
    5000
    • jdjjdj

      Ilmeisesti haluat listata esim varauskalenterin vapaatpäivät?

      Tällöin haet varauspäivät
      SELECT pvm FROM taulusi WHERE pvm > DATE_ADD(NOW(), INTERVAL -7 DAY);

      Sitten vain ohjelmointikielellä katsot ehtolauseella onko päivä varattu vai ei.


      Tässä pikkanen PHP esimerkki jotta tajunnet idean.

      • Aabo___

        Hei!

        Kiitos. Juuri tuollaista vähän tarvitsinkin. Mutta puhtaalla SQL:llä ilman php-virityksiä ei liene edes mahdollista?


      • jdjjdj
        Aabo___ kirjoitti:

        Hei!

        Kiitos. Juuri tuollaista vähän tarvitsinkin. Mutta puhtaalla SQL:llä ilman php-virityksiä ei liene edes mahdollista?

        Voisitko kertoa tarkemmin mihkä tuota tarttet? Jotenkin tuntuu oudolta, ettei haluta tietoja jota kannassa on vaan niitä jota siellä EI ole. Vai käsitinkös asiasi ihan väärin?

        Tietokannan(tietovaraston) ideahan on, että siellä on paljon tietoa joita haetaan erillaisilla haku ehdoilla.

        Toki kikkailemalla tuon haluamasi jutun pystyy tekemään. En sitten takaa toimiiko tämä ollenkaan koska on vielä vähän hakusessa tietokanta puolen ehtolauseet (eikä nyt ole mahdollista testatakkaan toimivuutta), I.Proqatlis osaa varmaankin sanoa toimivamman tavan.

        SELECT IF((SELECT TRUE FROM taulusi WHERE pvm = NOW()), NULL, NOW())
        UNION
        SELECT IF((SELECT TRUE FROM taulusi WHERE pvm = DATE_ADD(NOW(), INTERVAL -1 DAY)), NULL, DATE_ADD(NOW(), INTERVAL -1 DAY)))

        Lisäilet sitten noita UNIONeita tarvittavan määrän. Juu koodi on sitten luokkaa ;)


        Tosin kun haluat varauskalenterin niin silloinhan voisit lisätä esim parinvuoden päivät kantaan valmiiksi (tilan tarvehan on olematon) ja sitten tila sarakkeella onko päivä varattu tai mitä nyt tarttetkaan. Oletusarvona NULL

        Tuolloin asia onnistuu yksinkertaisella kyselyllä.
        SELECT pvm FROM taulusi WHERE pvm > DATE_ADD(NOW(), INTERVAL -7 DAY) AND tila = NULL


      • Aabo____
        jdjjdj kirjoitti:

        Voisitko kertoa tarkemmin mihkä tuota tarttet? Jotenkin tuntuu oudolta, ettei haluta tietoja jota kannassa on vaan niitä jota siellä EI ole. Vai käsitinkös asiasi ihan väärin?

        Tietokannan(tietovaraston) ideahan on, että siellä on paljon tietoa joita haetaan erillaisilla haku ehdoilla.

        Toki kikkailemalla tuon haluamasi jutun pystyy tekemään. En sitten takaa toimiiko tämä ollenkaan koska on vielä vähän hakusessa tietokanta puolen ehtolauseet (eikä nyt ole mahdollista testatakkaan toimivuutta), I.Proqatlis osaa varmaankin sanoa toimivamman tavan.

        SELECT IF((SELECT TRUE FROM taulusi WHERE pvm = NOW()), NULL, NOW())
        UNION
        SELECT IF((SELECT TRUE FROM taulusi WHERE pvm = DATE_ADD(NOW(), INTERVAL -1 DAY)), NULL, DATE_ADD(NOW(), INTERVAL -1 DAY)))

        Lisäilet sitten noita UNIONeita tarvittavan määrän. Juu koodi on sitten luokkaa ;)


        Tosin kun haluat varauskalenterin niin silloinhan voisit lisätä esim parinvuoden päivät kantaan valmiiksi (tilan tarvehan on olematon) ja sitten tila sarakkeella onko päivä varattu tai mitä nyt tarttetkaan. Oletusarvona NULL

        Tuolloin asia onnistuu yksinkertaisella kyselyllä.
        SELECT pvm FROM taulusi WHERE pvm > DATE_ADD(NOW(), INTERVAL -7 DAY) AND tila = NULL

        Kiitos vain. Niin kuin sanoinkin niin ongelmani ja tarpeeni jo oikeastaan ratkesivat tuon php:n myötä (se kyllä sisälsi pari pientä virhettä, mutta ei sillä merkitystä).

        Jatko oli nyt lähinnä vain sitä, että ihan mielenkiinnosta halusin juustiinsa tietää voiko tietokannasta "löytää" tavallaan asioita, mitä sieltä vielä puuttuu. Mutta se nyt vain oli lähinnä uteliaisuudesta. SQL:ssä kun ei oikein juuri noita silmukoita yms. ole.


      • jdjjdj
        Aabo____ kirjoitti:

        Kiitos vain. Niin kuin sanoinkin niin ongelmani ja tarpeeni jo oikeastaan ratkesivat tuon php:n myötä (se kyllä sisälsi pari pientä virhettä, mutta ei sillä merkitystä).

        Jatko oli nyt lähinnä vain sitä, että ihan mielenkiinnosta halusin juustiinsa tietää voiko tietokannasta "löytää" tavallaan asioita, mitä sieltä vielä puuttuu. Mutta se nyt vain oli lähinnä uteliaisuudesta. SQL:ssä kun ei oikein juuri noita silmukoita yms. ole.

        Kyl SQL:ssä onnistuu silmukatkin http://dev.mysql.com/doc/refman/5.0/en/while-statement.html ja mikäli tuon haluaisi SQL:llä tehdä niin se kannattaisi tehdä proseduuriksi/funktioksi jolloin voisi antaa parametrina monta päivää taakse/eteenpäin haluaisi. Näin olisi monikäyttöisempi.

        Juu esimerkit oli nopsasti tehty joten virheitä niissä on SQL esimerkissäkin sulku liikaa, mut idea kyllä niistä selviää.


    • I.Proqatlis

      Tuossa edellä heitettiin hiukan viittauksia meikäläiseen :-)

      Provosoiduin sen verran, että näytän, kuinka tämä homma voidaan tehdä! Tämä on myös vastaus kuvitelmaan, ettei esitettyä tehtävää lainkaan voisi ratkoa (My)SQL:llä.

      MySQL:ssä on mahdollista käyttää proseduureja, kuten yleensäkin relaatiokannoissa. Nämä proseduurit voivat ottaa vastaan tietoja ja palauttaa niitä. Niissä voidaan myös luoda tilapäisiä tauluja prosessointia varten ja operoida niillä.

      Olkoon meillä taulu nimeltä varaukset ja sen sisältö jotain tämäntapaista:

      id integer;
      varauspvm date;
      varausteksti varchar(100);

      Proseduuri ottaa vastaan päivien lukumäärän muuttujassa pvlukumaara.
      Alussa esitellään proseduurissa tarvittavat muuttujat declare-lauseilla. Muuttujien arvot asetetaan set-käskyllä.
      Huomatkaa, että muuttujan arvo (tässä tapauksessa muuttuvapaiva) voidaan asettaa SQL-operaatiolla, joka on sulkujen ympäröimä.

      Tämä on MySQL Query Browserin ikkunasta copypastettua toimivaa koodia. Siinä on runsaasti kommentteja asian ymmärtämiseksi.

      Tällainen proseduuri siis luodaan tietokantaan, jonka jälkeen sitä voidaan kutsua.

      MySQL Query Browserin ikkunasta sitä kutsutaan esim. näin: call mytest.VapaatPaivat(7);
      mytest on siis tietokannan nimi. Sitten seuraa proseduurin nimi.

      Käytännössä kutsujana voi olla vaikkapa javaohjelma tai PHP.

      Olisi varmasti hyvä tallettaa hakutulos aputauluun, josta sitten sovellusohjelma voisi käydä hakemassa vapaat päivät.

      Jätän sen lukijoille harjoitustehtäväksi :)

      Tämä tässä esitetty proseduuri pläjäyttää vapaat päivät heti ruutuun näkyviin.


      DELIMITER $$

      DROP PROCEDURE IF EXISTS `mytest`.`VapaatPaivat` $$
      CREATE PROCEDURE `mytest`.`VapaatPaivat` (in pvlukumaara integer)
      BEGIN
      declare muuttuvapaiva date;
      declare alkupaiva date;

      /* muuttuvapaiva: aseta alkuarvoksi tämänhetkinen päivä: */
      set muuttuvapaiva = ( select current_date() );

      /* alkupaiva: vähennä proseduuriin saapuva päivien lukumäärä tämänhetkisestä päivästä: */
      set alkupaiva = date_sub(muuttuvapaiva, interval pvlukumaara day);

      /* Luo aputaulu seuraavia operaatioita varten. Poista ensin mahdollinen vanha taulu */
      drop table if exists temp_table;
      create table temp_table ( testipaiva date not null );

      /* Kirjoita aputauluun jokainen tutkittavalla alueella oleva päivämäärä */

      while muuttuvapaiva >= alkupaiva do
      insert into temp_table (testipaiva) values (muuttuvapaiva);
      set muuttuvapaiva = date_sub(muuttuvapaiva, interval 1 day);
      end while;

      /* Hae aputaulusta ne päiväykset, joita ei esiinny varaukset-taulussa: */
      select * from temp_table a where not exists
      (select 1 from varaukset b
      where a.testipaiva = b.varauspvm);

      END $$

      DELIMITER ;

      • I.Proqatlis

        SQL-proseduurit ovat sitten selviä asioita, koskapa kukaan ei kysy mitään...?

        Tässä vielä toinen hiukan erilainen muunnelma samasta aiheesta kuin edellä. Proseduuri ottaa lähtökohdaksi eilispäivän päiväyksen ja vähentää siitä sen lukumäärän päiviä, joka saapuu proseduuriin muuttujassa pvlukumaara. Sitten käydään läpi kaikki tällä alueella olevat päivät ja katsotaan, esiintyykö vastaava päivä varaukset-taulussa. Jos ei esiinny, kirjoitetaan tämä päiväys aputauluun. Lopputulos on, että vapaat päivät on talletettu aputauluun, josta sitten on "maailman helpoin asia" käydä hakemassa ne yksinkertaisella selectillä.

        ----------------------------------------------------------------------------------


        DELIMITER $$

        DROP PROCEDURE IF EXISTS `mytest`.`VapaatPaivat` $$
        CREATE PROCEDURE `mytest`.`VapaatPaivat`(in pvlukumaara integer)
        BEGIN
        declare muuttuvapaiva date;
        declare alkupaiva date;
        declare maara integer;

        set muuttuvapaiva = date_sub( ( select current_date() ), interval 1 day );
        set alkupaiva = date_sub( muuttuvapaiva, interval pvlukumaara day );

        drop table if exists temp_vapaat_paivat;
        create table temp_vapaat_paivat ( testipaiva date not null );

        while muuttuvapaiva >= alkupaiva do
        set maara = ( select count(*) from varaukset where varauspvm = muuttuvapaiva );

        if maara = 0 then
        insert into temp_vapaat_paivat (testipaiva) values (muuttuvapaiva);
        end if;

        set muuttuvapaiva = date_sub( muuttuvapaiva, interval 1 day );

        end while;

        END $$

        DELIMITER ;


    Ketjusta on poistettu 1 sääntöjenvastaista viestiä.

    Luetuimmat keskustelut

    1. Jalankulkija kuoli. Poliisi etsii mustaa BMW Coupe -autoa, jossa on punertavat vanteet.

      Jalankulkija kuoli jäätyään auton alle Joensuussa – kuljettaja pakeni, poliisi pyytää havaintoja https://www.mtvuutiset.
      Joensuu
      192
      4465
    2. Mikä vasemmistolaisista jankkaavaa vaivaa?

      Pahasti on ihon alle, siis korvien väliin sinne tyhjään tilaan, päässeet kummittelemaan. Ei ole terveen ihmisen merkki
      Maailman menoa
      31
      3170
    3. Ohjelma "Rikollisjengien Ruotsi" hyvin paljasti jakautuneen maan

      eli ns. ruotsalaiset yhdellä puolella, muslimit ja muut kehitysmaalaiset toisella puolella. Siinäkin hyvin näki mitä ma
      Maailman menoa
      31
      2894
    4. PÄIVÄN PARAS: Nigerialainen haki turvapaikkaa Suomesta, lähti takas huilaamaan

      kotimaahansa, koska turvapaikan saaminen kesti niin kauan. Ja tämän kertoo ihan Yle, eikä yhtään toimittaja kyseenalaist
      Maailman menoa
      73
      2778
    5. Vassarina hymyilyttää vaurastuminen persujen kustannuksella

      Olen sijottanut määrätietoisesti osan Kelan tuista pörssiosakkeisiin, ja salkku on paisunut jo toiselle sadalle tuhanne
      Maailman menoa
      60
      2766
    6. Riikka runnoo: Elisalta potkut 400:lle

      Erinomaisen hallitusohjelman tavoite 100 000 työllistä lisää yksityisellä sektorilla on kohta saavutettu. Toivotaan toiv
      Maailman menoa
      90
      2625
    7. Pidennetään viikko 8 päiväiseksi

      Ja jätetään työpäivien määrä nykyiseen 5:een. Tuo olisi kompromissiratkaisu vellovaan keskusteluun työajan lyhentämisest
      Maailman menoa
      14
      2351
    8. Pääseekö kuka tahansa hoitaja katselemaan kenen tahansa ihmisen terveystietoja?

      "Meeri selaili puhelinta uteliaisuuttaan ja katuu nyt – Moni hoitaja on tehnyt saman rikoksen Tuttujen ihmisten asiat k
      Maailman menoa
      100
      2119
    9. Miksi eristäydyt?

      Onko jokin syy kun vetäydyt omiin oloihin?
      Ikävä
      112
      1297
    10. Missä me nähtiin viimeksi nainen

      Paikka ja siitä vähän kuvailua. Mitä kohtaamisessa tapahtui?
      Ikävä
      63
      1128
    Aihe