Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: Seuraavan päivän kaikki tapahtumat

Sivun loppuun

SysRq868 [14.07.2008 20:24:41]

#

Minulla on lista tapahtumista MySQL:ssä tähän tapaan:

+------+--------+------+--------------+----------------------+
| tid  | month  | day  | title        | timestamp            |
+------+--------+------+--------------+----------------------+
| 1    | 03     | 11   | Konsertti    | 2008-05-03 11:57:58  |
| 2    | 04     | 09   | Talkoopäivä  | 2008-05-03 11:59:08  |
| 3    | 04     | 09   | Pullakahvit  | 2008-05-03 11:59:32  |
| 4    | 08     | 29   | Rantaloma    | 2008-05-03 12:00:09  |
+------+--------+------+--------------+----------------------+

tid on siis auto_increment-ID tiedolle, month tapahtuman päivämäärän kuukausi, day tapahtuman päivämäärän päivä, title tapahtuman nimi ja timestamp tapahtuman lisäämispäivä hallintapaneelista.

Pohja on vanha, ja nyt kun katselin sitä sivuston uudelleenkirjoituksen yhteydessä, huomasin systeemin olevan idioottimainen. Se ei esim. kerro tapahtuman kellonaikaa.

Tarkoitus olisi muuttaa taulu tällaiseen muotoon:

+------+----------------------+--------------+----------------------+
| tid  | eventdate            | title        | timestamp            |
+------+----------------------+--------------+----------------------+
| 1    | 2008-03-15 18:00:00  | Konsertti    | 2008-05-03 11:57:58  |
| 2    | 2008-04-09 17:30:00  | Talkoopäivä  | 2008-05-03 11:59:08  |
| 3    | 2008-04-09 19:30:00  | Pullakahvit  | 2008-05-03 11:59:32  |
| 4    | 2008-08-29 08:00:00  | Rantaloma    | 2008-05-03 12:00:09  |
+------+----------------------+--------------+----------------------+

Nyt siis pitäisi saada aikaan tälle uudella formaatilla toimiva boksi, joka kertoo seuraavan tapahtuman nimen (tänään se siis olisi "Rantaloma"). Tämä olisi minulle helppoa, mutta kun taulussa voi olla samalle päivälle useampi tapahtuma. Miten näinä päivinä voisi aikajärjestyksessä näyttää tulevat tapahtumat seuraavalta tapahtumapäivältä? Siis huhtikuun 1. päivä kun katsoisi, näkisi

17:30 - Talkoopäivä
19:30 - Pullakahvit

Kellonajat osaan hakea ja kirjoitella itsekin, hakusessa on vain tapa hakea seuraava päivämäärä ja aikajärjestyksessä kaikki sinä päivänä tapahtuvat tapahtumat. Miten siis sellaisen haun voisi suorittaa?

Kiitos syvä.

TsaTsaTsaa [14.07.2008 21:41:45]

#

Suunnilleen näin pitäisi onnistua:

SELECT eventdate.kello, title
FROM tapahtumat
WHERE eventdate.pvm IN (
   SELECT eventdate.pvm
   FROM tapahtumat
   WHERE eventdate > NOW
   LIMIT 1
)
ORDER BY 1 ASC;

SQL vähän hakusessa, mutta tässä eventdate.kello tarkoittaa eventdatesta parsittua kellonaikaa ja eventdate.pvm päivämäärää (en muista miten se tehtiin, taisi jotenkin FORMAT-käskyllä tjms. saada).

EDIT: Ja ASC:n tilalle vissiin kuitenkin DESC, nyt ei aivot pelitä...Jompi kumpi kuitenkin.

ajv [14.07.2008 22:55:26]

#

Yksi vaihtoehto on hoitaa ihan PHP:n puolella sen kyselyn muodostaminen:

<?php
$tomorrow = date("Y-m-d", time() + 86400);

$sql = "SELECT
	eventdate,
	title
FROM
	tapahtumat
WHERE
	DATE_FORMAT(eventdate, '%Y-%m-%d') = '".$tomorrow."'";
?>

TsaTsaTsaa [14.07.2008 22:56:55]

#

Paitsi että kyseessä ei ollut huominen vaan seuraava päivä jolloin on tapahtumia.

ajv [14.07.2008 22:59:24]

#

Aivan! Sisälukutaito kunniaan :) Eli siis unohtakaa tuo edellinen viestini... :)

SysRq868 [15.07.2008 20:00:32]

#

Mikä siis toimisi käytännössä?

Tällainenkö?

SELECT eventdate, title
FROM tapahtumat
WHERE DATE_FORMAT(eventdate, '%Y-%m-%d') IN (
   SELECT DATE_FORMAT(eventdate, '%Y-%m-%d')
   FROM tapahtumat
   WHERE eventdate > NOW
   LIMIT 1
) ORDER BY 1 ASC;

TsaTsaTsaa [15.07.2008 21:33:48]

#

Ihan toimivalta näyttää.

EDIT: Siis jos NOW antaa nykyhetken.

Metabolix [15.07.2008 21:48:10]

#

MySQL tarjoaa käyttöön myös muuttujat, joten voit ensin hakea lähimmän seuraavan tapahtuman ajankohdan ja vasta sitten sopivat tapahtumat, esimerkiksi siis näin:

SET @min_aika = (SELECT MIN(aika) FROM taulu WHERE aika > NOW());
SELECT * FROM taulu WHERE aika BETWEEN @min_aika AND (@min_aika + INTERVAL 1 DAY) ORDER BY aika;

Tällä kyselyllä saat seuraavasta tapahtumasta enintään vuorokauden päässä olevat tapahtumat. En jaksanut nyt niin tarkkaan lukea, että tietäisin, mitä aivan täsmälleen haluat saada, mutta kysy lisää, jos ei tällä selviä. :)

Minulle tuli tuollaisesta alikyselyä käyttävästä ratkaisusta tällainen virheilmoitus:
ERROR 1137 (HY000): Can't reopen table: 'taulu'

SysRq868 [16.07.2008 20:00:59]

#

Siis tarkoitus oli saada seuraava tapahtumapäivä.

Jos tänään olisi 3.5., 4.5. ei tapahdu mitään ja aikajärjestyksessä seuraavat kaksi tapahtumaa ovat molemmat 13.5., pitäisi ne ja vain ne tapahtumat saada käsiteltäviksi.


Ja tuo kirjoittamani kysely ei toimi. mysql_fetch_array(): supplied argument is not a valid MySQL result resource.

Metabolix [17.07.2008 10:41:44]

#

Käytä virheen selvittämiseen mysql_error-funktiota.

<?php
$r = mysql_query($q);
if (!$r) {
  die("MySQL-virhe (mysql_query): ".mysql_error());
}
?>

Tekemäni kyselyn pitäisi vastata tarpeitasi, kunhan pyöristät NOW-arvon ylös seuraavaan keskiyöhön, jotta tarkistus alkaisi seuraavasta päivästä, ja saadun min_aika-arvon vastaavasti alaspäin, jotta tulokset olisivat kaikki samalta päivältä.

SysRq868 [17.07.2008 20:41:08]

#

mysql_error tuotti sen saman minkä aina: "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '; SELECT * FROM kalenteri WHERE eventdate BETWEEN @min_aika AND (@min_aika + IN' at line 1".

Miten pyöristän nuo arvot?

TsaTsaTsaa [17.07.2008 21:47:51]

#

Eikö näin onnistuisi?

<?php
$sql = "SELECT DATE_FORMAT(eventdate, '%Y-%m-%D')
        FROM kalenteri
        WHERE eventdate > NOW()
        LIMIT 1";

$seuraavapvm = mysql_result( mysql_query($sql, $link), 0, 0 );

$sql = "SELECT eventdate, title
        FROM kalenteri
        WHERE DATE_FORMAT(eventdate, '%Y-%m-%d') = $seuraavapvm
        ORDER BY eventdate";

// ...
?>

Testaamatonta toki.

ajv [17.07.2008 22:13:03]

#

TsaTsaTsaan koodi on oikeilla jäljillä, mutta hakee tämän päivän tapahtumat, jos tapahtuman kellonaika ei ole vielä kulunut umpeen - en tiedä onko tarkoituksenmukaista? Lisäksi ekaan kyselyyn laittaisin ORDER BY eventdate ja jälkimmäiseen kyselyyn hipsut $seuraavapvm-muuttujan ympärille.

Tässä vielä omat versioni kyselyistä:

<?php
// Haetaan seuraavan tapahtuman päivämäärä (kuluvan päivän tapahtumat suljettu laskuista pois)
$nextDate = $db->get_value("
SELECT
   DATE_FORMAT(eventdate, '%Y-%m-%d') AS pvm
FROM
   tapahtumat
HAVING
   pvm > DATE_FORMAT(NOW(), '%Y-%m-%d')
ORDER BY
   eventdate
LIMIT 1");

//Haetaan ko. päivämäärän tapahtumat
$results = $db->get_all("
SELECT
   eventdate,
   title
FROM
   tapahtumat
WHERE
   DATE_FORMAT(eventdate, '%Y-%m-%d') = '".$nextDate."'
ORDER BY
   eventdate");
?>

Edit: Tämä ei ehkä ole optimaalisin tapa, mutta jos tapahtumia ei ole kovin paljon, niin käytännössä haun optimoinnilla ei ole mitään merkitystä.

SysRq868 [19.07.2008 22:28:15]

#

Hmm, mikäs tuo $db on?

ajv [20.07.2008 14:11:31]

#

Se on kuvitteellinen tietokantaluokka, koska en jaksanut kirjottaa noita rivienhakurutiineja "oikeaoppisesti" tarkistuksineen tuohon. Otat tosta vaan nuo kyselyt ja loput sovellat itse.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta