Autor Zpráva
mackopu
Profil
Mám tabulku událostí:
CREATE TABLE `events` (
  `id` int(11) NOT NULL auto_increment,
  `titulek` varchar(255) NOT NULL,
  `popis` text NOT NULL,
  `date` date NOT NULL,
  `time` time NOT NULL,
  `date_to` date NOT NULL,
  `recursive` varchar(7) NOT NULL,
  `recursive_to` date NOT NULL,
  PRIMARY KEY  (`id`)
);

"time", "date_to", "recursive" a "recursive_to" mohou být prázdné (respektive u časových a datových formátů 00:00:00 či 0000-00-00). "Recursive" může být rovněž yearly, monthly nebo weekly.
A nyní potřebuji vybrat záznamy, které se týkají dnešního dne, tj. něco jako
SELECT titulek FROM events WHERE date = '2008-03-12'
Ale to je málo, protože jestliže má nějaká událost jako "date" vloženo 2008-03-12 a "recursive" yearly, pak by se měla vypsat i příští rok ve stejný den.
Jak na to?
ninja
Profil
mackopu: Nemas uplne nejlepe navrzenou strukturu databaze. Mel bys mit tabulku events kde by byl titulek, popis a tak a pak tabulku events_instants kde by byly instance daneho eventu. Sloupce date, event_id. Jeden event ma vice instanci.

Pri vlozeni noveho eventu mu dle nastaveni (napriklad kazdorocni opakovani) vytvoris odpovidajici pocet radek v events_instants.

Pokud nemuzes menit strukturu, tak asi neco jako:

SELECT titulek FROM events WHERE date = '2008-03-12' OR (recursive_to <= '2008-03-12' AND recursive = 'monthly' AND DAY(date) = '12');
mackopu
Profil
Strukturu opravdu měnit nemohu.
Zkusím to a dám vědět, díky.
mackopu
Profil
Tak tohle funguje dobře pro měsíční a roční opakování:
SELECT titulek 
FROM events
WHERE date = '2008-03-13'
OR (
recursive_to <= '2008-03-13'
AND recursive = 'monthly'
AND DAY( date ) = '13'
)
OR (
recursive_to <= '2008-03-13'
AND recursive = 'yearly'
AND DAY( date ) = '13'
AND MONTH( date ) = '03'
)
Co ale s opakováním týdenním?
OR (recursive_to <= '2008-03-13' AND recursive = 'weekly' ... )
nightfish
Profil
Co ale s opakováním týdenním?
potřebuješ, aby rozdíl dvou uvedených datumů, vyjádřený ve dnech, byl dělitelný sedmi (resp. jeho celá část aby byla dělitelná sedmi)
DATEDIFF(datum1, datum2) MOD 7 = 0
Kajman_
Profil *
Co ale s opakováním týdenním?
dayofweek(date)=dayofweek('2008-03-13')

Ale osobně bych také měnil strukturu. Asi bych si tam předpočítával při spuštění události datum dalšího spuštění (asi ze dvou sloupečků, počet dnů a počet měsíců pro opakování). Ty podmínky, co teď máte, nebudou fungovat korektně. Třeba měsíční opakovaní k 31.3. se nebude opakovat měsíčně. Ani roční opakovaní k 29.2. se nebude opakovat ročně.
ninja
Profil
mackopu:
DATEDIFF(datum1, datum2) MOD 7 = 0

Pokud jedes na Mysql < 4.1 kde neni DADIFF, tak muzes pouzit:

(TO_DAYS(datum1) - TO_DAYS(datum2)) MOD 7 = 0
ninja
Profil
Kajman_: Ty podmínky, co teď máte, nebudou fungovat korektně. Třeba měsíční opakovaní k 31.3. se nebude opakovat měsíčně. Ani roční opakovaní k 29.2. se nebude opakovat ročně.

Presne. Neni divu ze prakticky ve vsech aplikacich se pri nastaveni periodickeho opakovani rovnou predvyplni instance do daleke budoucnosti (vetsinou 2038, stejne vic ve svete unix timestampu nema smysl).
mackopu
Profil
Opravdu nic měnit nemohu.
Nefunkční opakování v uvedených příkladech je ošetřeno při zadávání do formuláře.

A nyní:
SELECT titulek FROM events
WHERE date = '2008-03-13'
OR (
  recursive_to <= '2008-03-13'
  AND recursive = 'weekly'
  AND DAYOFWEEK(date) = DAYOFWEEK('2008-03-13')
)
OR (
  recursive_to <= '2008-03-13'
  AND recursive = 'monthly'
  AND DAY(date) = '13'
)
OR (
  recursive_to <= '2008-03-13'
  AND recursive = 'yearly'
  AND DAY(date) = '13'
  AND MONTH(date) = '03'
)
Funguje, ovšem při testu je ve výpisu i událost, která má date 2008-05-29, recursive weekly a recursive_to 0000-00-00. Něco je špatně...
mackopu
Profil
Tak tohle už chodí:
SELECT titulek FROM events
WHERE date = '2008-03-13'
OR (
  '2008-03-13' >= date
  AND recursive_to <= '2008-03-13'
  AND recursive = 'weekly'
  AND DAYOFWEEK(date) = DAYOFWEEK('2008-03-13')
)
OR (
  '2008-03-13' >= date
  AND recursive_to <= '2008-03-13'
  AND recursive = 'monthly'
  AND DAY(date) = '13'
)
OR (
  '2008-03-13' >= date
  AND recursive_to <= '2008-03-13'
  AND recursive = 'yearly'
  AND DAY(date) = '13'
  AND MONTH(date) = '03'
)
Á propos - potřeboval jsem to pro rozesílání informačních e-mailů cronem. Díky moc všem za spolupráci.
Toto téma je uzamčeno. Odpověď nelze zaslat.