2012-05-11 17 views
12

Próbuję iść na niesławne powtarzające się wydarzenia na kalendarze przy użyciu PHP/MySQL. W końcu znalazłem coś, co wydaje się działać. Znalazłem moją answer here, ale mam niewielki problem z jej wykończeniem.Powtarzające się wydarzenia w kalendarzu i niektóre końcowe matematyki

Moja pierwsza tabela "zdarzenia".

ID NAME 
1  Sample Event 
2  Another Event 

Moja druga tabela "events_meta, która przechowuje powtarzające się dane.

ID event_id  meta_key   meta_value 
1  1    repeat_start  1336312800 /* May 7th 2012 */ 
2  1    repeat_interval_1 432000 /* 5 days */ 

z repeat_start jest data bez czasie datownika UNIX i repeat_interval ilość czasu pomiędzy przerwami (432000 jest 5 dni).

Następnie mam następujący MySQL, który nieznacznie zmodyfikowałem z powyższego linku. Znacznik czasu użyty poniżej (1299132000, czyli 12 maja 2012 r.) Jest bieżącym dniem bez żadnego czasu.

SELECT EV.* 
FROM `events` EV 
RIGHT JOIN `events_meta` EM1 ON EM1.`event_id` = EV.`id` 
RIGHT JOIN `events_meta` EM2 ON EM2.`meta_key` = CONCAT('repeat_interval_', EM1.`id`) 
WHERE EM1.meta_key = 'repeat_start' 
    AND (
     (CASE (1336744800 - EM1.`meta_value`) 
      WHEN 0 
       THEN 1 
      ELSE (1336744800 - EM1.`meta_value`)/EM2.`meta_value` 
      END 
     ) 
    ) = 1 

W powyższym MySQL następujący kod pobiera pole repeat_start (EM1.'meta_value') od bieżącej daty, a następnie dzieli się przez pole przedziału powtarzania (EM2.'meta_value').

ELSE (1336744800 - EM1.`meta_value`)/EM2.`meta_value` 

LUB

TODAYS DATE - START DATE/5 DAYS 

Więc oto matematyki:

1336744800 - 1336312800 = 432000 
432000/432000 = 1 

że teraz działa idealnie. Ale gdybym 5 dni naprzód zmienić aktualny timestamp do 1336312800, która jest 17-te Mat 2012, to wygląda trochę tak:

1336312800 - 1336312800 = 864000 
86400/432000 = 2 

Które nie działa, ponieważ jest równy 2, a w MySQL musi wynosić 1 Tak więc domyślam się, że moje pytanie brzmi: w jaki sposób mogę uzyskać, że MySQL rozpoznaje liczbę całkowitą, zamiast tego robić?

... 
WHERE EM1.meta_key = 'repeat_start' 
    AND (
     (CASE (1336744800 - EM1.`meta_value`) 
      WHEN 0 
       THEN 1 
      ELSE (1336744800 - EM1.`meta_value`)/EM2.`meta_value` 
      END 
     ) 
    ) = IN (1,2,3,4,5,6,7,8,....) 

Nadzieja Robię sens i mam nadzieję, że to tylko prosta matematyka rzeczą lub funkcją, że MySQL ma że pomoże :) Dzięki za pomoc!

EDIT: Odpowiedź

Dzięki @eggypal poniżej, znalazłem moją odpowiedź i oczywiście było to proste!

SELECT EV.* 
FROM elvanto_calendars_events AS EV 
RIGHT JOIN elvanto_calendars_events_meta AS EM1 ON EM1.`event_id` = EV.`id` 
RIGHT JOIN elvanto_calendars_events_meta AS EM2 ON EM2.`meta_key` = CONCAT('repeat_interval_', EM1.`id`) 
WHERE EM1.meta_key = 'repeat_start' 
AND ((1336744800 - EM1.`meta_value`) % EM2.`meta_value`) = 0 
+1

Data obliczenia matematyki na podstawie znaczników czasu i ustalonej liczby sekund w ciągu dnia spowoduje przekroczenie wartości czasu letniego. – DCoder

+1

Dobre połączenie @DCoder. Przechowuję wszystkie moje czasy jako GMT, a następnie używam funkcji CONVERT_TZ do ustalenia daty 'repeat_start'. Powyższe przykłady kodu nie zawierają tego dodatkowego kodu. Myślę, że to powinno wystarczyć? –

+0

Twoje zapytanie pozwoli mi zobaczyć wynik dla podanej daty początkowej i końcowej? '1336744800' wygląda jak konkretny dzień :( –

Odpowiedz

10

To nie jest do końca jasne, co chcesz zapytanie do zrobić, ale jist swoje pytanie sprawia, że ​​skłania się ku sugerując, że patrzysz na modułowej arytmetyki: SQL, a % b zwraca pozostałą gdy a jest dzielona przez b - jeśli nie ma żadnej reszty (tj. a % b = 0), wówczas a musi być dokładną wielokrotnością z b.

W twoim przypadku, myślę starasz się znaleźć zdarzenia, gdzie czas między zdarzeniem a niektóre zaczynają dany literał jest dokładną wielokrotnością przedziału zdarzeń, to znaczy (literal - event_start) % event_interval = 0. Jeśli jest niezerowa, wartość jest czasem do następnego wystąpienia po literal (i, w związku z tym, do ustalenia, czy to następne wystąpienie nastąpi w pewnym okresie czasu, powiedzmy dzień, można przetestować, aby zobaczyć, czy reszta jest mniejsza niż taka stała, np. (literal - event_start) % event_interval < 86400).

Jeśli nie o to nam chodzi, proszę dokładnie wyjaśnić, co próbuje osiągnąć twoje zapytanie.

+0

To jest sztuczka! Udało mi się uruchomić ją w PHP: 'echo ((strtotime ('2012-05-22 00:00:00') - 1336312800)% 432000);' Próbowałem używać '%' w MySQL, ale to nie działało.jest ich odpowiednikiem? –

+0

Przepraszamy , zignorujcie mój ostatni komentarz, zadziałało! Będę edytować mój oryginalny post z ostatecznym kodem, aby pomóc innym :) –

+0

Zacząłem go śledzić i nie udało mi się. Pomóż mi. http://stackoverflow.com/questions/20286332/display-next-event-date – Billa

Powiązane problemy