database-design - कैलेंडर आवर्ती / दोहराव घटनाक्रम-सर्वश्रेष्ठ संग्रहण विधि




calendar (10)

मैं एक कस्टम इवेंट सिस्टम बना रहा हूं, और यदि आपके पास ऐसा दोहराव वाला ईवेंट है जो इस तरह दिखता है:

इवेंट ए 3 मार्च, 2011 से शुरू होने वाले हर 4 दिनों को दोहराता है

या

इवेंट बी 1 मार्च, 2011 से मंगलवार को हर 2 सप्ताह दोहराता है

मैं इसे डेटाबेस में कैसे संग्रहीत कर सकता हूं जिससे लुकअप करना आसान हो जाए। यदि बड़ी संख्या में ईवेंट हैं, तो मुझे प्रदर्शन संबंधी मुद्दों नहीं चाहिए, और कैलेंडर को प्रतिपादित करते समय मुझे प्रत्येक के माध्यम से जाना होगा।


Answers

आप सभी में रुचि रखने वालों के लिए, अब आप केवल मिनटों के भीतर शुरू करने के लिए कॉपी और पेस्ट कर सकते हैं। मैंने टिप्पणियों में सलाह दी और साथ ही मैं कर सकता था। अगर मुझे कुछ याद आ रहा है तो मुझे बताएं।

"कॉम्प्लेक्स संस्करण":

आयोजन

+----------+----------------+
| ID       | NAME           | 
+----------+----------------+
| 1        | Sample event 1 |
| 2        | Second  event  |
| 3        | Third event    |
+----------+----------------+

events_meta

+----+----------+--------------+------------------+-------------+--------------+------------+-------------+----------------+
| ID | event_id | repeat_start | repeat_interval  | repeat_year | repeat_month | repeat_day | repeat_week | repeat_weekday |
+----+----------+--------------+------------------+-------------+--------------+------------+-------------+----------------+
| 1  | 1        | 2014-07-04   | 7                | NULL        | NULL         | NULL       | NULL        | NULL           |
| 2  | 2        | 2014-06-26   | NULL             | 2014        | *            | *          | 2           | 5              |
| 3  | 3        | 2014-07-04   | NULL             | *           | *            | *          | *           | 5              |
+----+----------+--------------+------------------+-------------+--------------+------------+-------------+----------------+

एसक्यूएल कोड:

CREATE TABLE IF NOT EXISTS `events` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `NAME` varchar(255) NOT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=7 ;

--
-- Dumping data for table `events`
--

INSERT INTO `events` (`ID`, `NAME`) VALUES
(1, 'Sample event'),
(2, 'Another event'),
(3, 'Third event...');

CREATE TABLE IF NOT EXISTS `events_meta` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `event_id` int(11) NOT NULL,
  `repeat_start` date NOT NULL,
  `repeat_interval` varchar(255) NOT NULL,
  `repeat_year` varchar(255) NOT NULL,
  `repeat_month` varchar(255) NOT NULL,
  `repeat_day` varchar(255) NOT NULL,
  `repeat_week` varchar(255) NOT NULL,
  `repeat_weekday` varchar(255) NOT NULL,
  PRIMARY KEY (`ID`),
  UNIQUE KEY `ID` (`ID`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ;

--
-- Dumping data for table `events_meta`
--

INSERT INTO `events_meta` (`ID`, `event_id`, `repeat_start`, `repeat_interval`, `repeat_year`, `repeat_month`, `repeat_day`, `repeat_week`, `repeat_weekday`) VALUES
(1, 1, '2014-07-04', '7', 'NULL', 'NULL', 'NULL', 'NULL', 'NULL'),
(2, 2, '2014-06-26', 'NULL', '2014', '*', '*', '2', '5'),
(3, 3, '2014-07-04', 'NULL', '*', '*', '*', '*', '1');

MySQL निर्यात के रूप में भी उपलब्ध है (आसान पहुंच के लिए)

PHP उदाहरण कोड index.php:

<?php
    require 'connect.php';    

    $now = strtotime("yesterday");

    $pushToFirst = -11;
    for($i = $pushToFirst; $i < $pushToFirst+30; $i++)
    {
        $now = strtotime("+".$i." day");
        $year = date("Y", $now);
        $month = date("m", $now);
        $day = date("d", $now);
        $nowString = $year . "-" . $month . "-" . $day;
        $week = (int) ((date('d', $now) - 1) / 7) + 1;
        $weekday = date("N", $now);

        echo $nowString . "<br />";
        echo $week . " " . $weekday . "<br />";



        $sql = "SELECT EV.*
                FROM `events` EV
                RIGHT JOIN `events_meta` EM1 ON EM1.`event_id` = EV.`id`
                WHERE ( DATEDIFF( '$nowString', repeat_start ) % repeat_interval = 0 )
                OR ( 
                    (repeat_year = $year OR repeat_year = '*' )
                    AND
                    (repeat_month = $month OR repeat_month = '*' )
                    AND
                    (repeat_day = $day OR repeat_day = '*' )
                    AND
                    (repeat_week = $week OR repeat_week = '*' )
                    AND
                    (repeat_weekday = $weekday OR repeat_weekday = '*' )
                    AND repeat_start <= DATE('$nowString')
                )";
        foreach ($dbConnect->query($sql) as $row) {
            print $row['ID'] . "\t";
            print $row['NAME'] . "<br />";
        }

        echo "<br /><br /><br />";
    }
?>

PHP उदाहरण कोड connect.php:

<?
// ----------------------------------------------------------------------------------------------------
//                                       Connecting to database
// ----------------------------------------------------------------------------------------------------
// Database variables
$username = "";
$password = "";
$hostname = ""; 
$database = ""; 

// Try to connect to database and set charset to UTF8
try {
    $dbConnect = new PDO("mysql:host=$hostname;dbname=$database;charset=utf8", $username, $password);
    $dbConnect->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

} catch(PDOException $e) {
    echo 'ERROR: ' . $e->getMessage();
}
// ----------------------------------------------------------------------------------------------------
//                                      / Connecting to database
// ----------------------------------------------------------------------------------------------------
?>

इसके अलावा PHP कोड यहां उपलब्ध है (बेहतर पठनीयता के लिए):
index.php
तथा
connect.php
अब इसे स्थापित करने में आपको मिनट लग सकते हैं। घंटे नहीं :)


पैटर्न "सरल" दोहराना पैटर्न

मेरे PHP / MySQL आधारित कैलेंडर के लिए, मैं दोहराने / पुनरावर्ती घटना की जानकारी को यथासंभव कुशलतापूर्वक स्टोर करना चाहता था। मैं बड़ी संख्या में पंक्तियां नहीं लेना चाहता था, और मैं एक विशिष्ट तारीख पर होने वाली सभी घटनाओं को आसानी से देखना चाहता था।

नियमित अंतराल पर होने वाली दोहराने वाली जानकारी को संग्रहीत करने के लिए नीचे दी गई विधि बहुत अच्छी है, जैसे हर दिन, हर दिन, हर सप्ताह, हर महीने, हर महीने, हर महीने इत्यादि। इसमें हर मंगलवार और गुरुवार के प्रकार के पैटर्न भी शामिल होते हैं, क्योंकि वे संग्रहीत होते हैं अलग-अलग हर हफ्ते एक मंगलवार से शुरू होता है और प्रत्येक सप्ताह गुरुवार से शुरू होता है।

मान लीजिए मेरे पास दो टेबल हैं, जिन्हें इस तरह की events कहा जाता है:

ID    NAME
1     Sample Event
2     Another Event

और events_meta नामक एक टेबल इस तरह है:

ID    event_id      meta_key           meta_value
1     1             repeat_start       1299132000
2     1             repeat_interval_1  432000

दोहराना_स्टार्ट एक यूनिक्स टाइमस्टैम्प के रूप में कोई समय नहीं होने के साथ, और intervals के बीच सेकंड में दोहराव_interval (432000 5 दिन है) के साथ।

repeat_interval_1 आईडी 1 की repeat_start के साथ चला जाता है। इसलिए यदि मेरे पास एक ऐसा ईवेंट है जो प्रत्येक मंगलवार और हर गुरुवार को दोहराता है, तो repeat_interval 604800 (7 दिन) होगा, और 2 repeat_starts और 2 repeat_intervals होंगे। तालिका इस तरह दिखेगी:

ID    event_id      meta_key           meta_value
1     1             repeat_start       1298959200 -- This is for the Tuesday repeat
2     1             repeat_interval_1  604800
3     1             repeat_start       1299132000 -- This is for the Thursday repeat
4     1             repeat_interval_3  604800
5     2             repeat_start       1299132000
6     2             repeat_interval_5  1          -- Using 1 as a value gives us an event that only happens once

फिर, यदि आपके पास कैलेंडर है जो हर दिन लूप करता है, तो उस दिन के लिए ईवेंट को पकड़ना, क्वेरी इस तरह दिखेगी:

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 ( 1299132000 - EM1.`meta_value` )
            WHEN 0
              THEN 1
            ELSE ( 1299132000 - EM1.`meta_value` )
          END
        ) / EM2.`meta_value`
    ) = 1
LIMIT 0 , 30

वर्तमान तिथि के लिए यूनिक्स टाइमस्टैम्प के साथ {current_timestamp} को प्रतिस्थापित करना (समय कम करना, इसलिए घंटा, मिनट और दूसरा मान 0 पर सेट किया जाएगा)।

उम्मीद है कि यह किसी और की भी मदद करेगा!

पैटर्न "दोहराना" पैटर्न पैटर्न

यह विधि जटिल पैटर्न जैसे भंडारण के लिए बेहतर अनुकूल है

Event A repeats every month on the 3rd of the month starting on March 3, 2011

या

Event A repeats Friday of the 2nd week of the month starting on March 11, 2011

मैं सबसे लचीलापन के लिए उपर्युक्त सिस्टम के साथ संयोजन करने की सिफारिश करता हूं। इसके लिए टेबल इस तरह होना चाहिए:

ID    NAME
1     Sample Event
2     Another Event

और events_meta नामक एक टेबल इस तरह है:

ID    event_id      meta_key           meta_value
1     1             repeat_start       1299132000 -- March 3rd, 2011
2     1             repeat_year_1      *
3     1             repeat_month_1     *
4     1             repeat_week_im_1   2
5     1             repeat_weekday_1   6

repeat_week_im वर्तमान महीने के सप्ताह का प्रतिनिधित्व करता है, जो संभावित रूप से 1 से 5 के बीच हो सकता है। सप्ताह के दिन repeat_weekday , repeat_weekday 1-7।

अब यह मानते हुए कि आप अपने कैलेंडर में एक महीने का दृश्य बनाने के लिए दिन / सप्ताह के माध्यम से लूप कर रहे हैं, आप इस तरह की एक क्वेरी लिख सकते हैं:

SELECT EV . *
FROM `events` AS EV
JOIN `events_meta` EM1 ON EM1.event_id = EV.id
AND EM1.meta_key = 'repeat_start'
LEFT JOIN `events_meta` EM2 ON EM2.meta_key = CONCAT( 'repeat_year_', EM1.id )
LEFT JOIN `events_meta` EM3 ON EM3.meta_key = CONCAT( 'repeat_month_', EM1.id )
LEFT JOIN `events_meta` EM4 ON EM4.meta_key = CONCAT( 'repeat_week_im_', EM1.id )
LEFT JOIN `events_meta` EM5 ON EM5.meta_key = CONCAT( 'repeat_weekday_', EM1.id )
WHERE (
  EM2.meta_value =2011
  OR EM2.meta_value = '*'
)
AND (
  EM3.meta_value =4
  OR EM3.meta_value = '*'
)
AND (
  EM4.meta_value =2
  OR EM4.meta_value = '*'
)
AND (
  EM5.meta_value =6
  OR EM5.meta_value = '*'
)
AND EM1.meta_value >= {current_timestamp}
LIMIT 0 , 30

उपर्युक्त विधि के साथ संयुक्त इसे सबसे दोहराने / पुनरावर्ती घटना पैटर्न को कवर करने के लिए जोड़ा जा सकता है। अगर मुझे कुछ याद आ गया है तो कृपया एक टिप्पणी छोड़ दें।


संवर्द्धन: तिथि के साथ टाइमस्टैम्प को प्रतिस्थापित करें

स्वीकृत उत्तर में एक छोटे से वृद्धि के रूप में जिसे बाद में अफ़ोफर द्वारा परिष्कृत किया गया था - टाइमस्टैम्प की बजाय दिनांक प्रारूप का उपयोग करना संभव है। फायदे हैं:

  1. डेटाबेस में पठनीय तिथियां
  2. वर्षों के साथ कोई समस्या नहीं> 2038 और टाइमस्टैम्प
  3. हटाए जाने वाले समय-समय पर सावधानी बरतने की ज़रूरत है जो मौसमी समायोजित तिथियों पर आधारित हैं यानि 28 जून को 28 दिसंबर से एक घंटा पहले शुरू होता है, इसलिए एक तिथि से टाइमस्टैम्प प्राप्त करने से रिकर्सन एल्गोरिदम टूट सकता है।

ऐसा करने के लिए, डीबी repeat_start को प्रकार 'दिनांक' के रूप में संग्रहीत करने के लिए बदलें और repeat_interval अब सेकंड के बजाए दिन रखें। यानी 7 दिनों की दोहराव के लिए 7।

एसक्यूएल लाइन बदलें: जहां ((1370563200 - repeat_start)% repeat_interval = 0)

करने के लिए: जहां (DATEDIFF ('2013-6-7', event_start)% repeat_interval = 0)

बाकी सब कुछ वैसा ही रहता है। साधारण!


आपके द्वारा दिए गए दो उदाहरण बहुत सरल हैं; उन्हें एक साधारण अंतराल के रूप में प्रदर्शित किया जा सकता है (पहला चार दिन होता है, दूसरा 14 दिन होता है)। आप इसे कैसे मॉडल करते हैं, यह पूरी तरह से आपके पुनरावर्तन की जटिलता पर निर्भर करेगा। यदि आपके ऊपर जो कुछ है वह सचमुच सरल है, तो दोहराना अंतराल में प्रारंभ तिथि और दिनों की संख्या संग्रहित करें।

यदि, हालांकि, आपको चीजों का समर्थन करने की आवश्यकता है

इवेंट ए 3 मार्च, 2011 से शुरू होने वाले महीने के तीसरे महीने हर महीने दोहराता है

या

इवेंट ए 11 मार्च, 2011 से शुरू होने वाले महीने के दूसरे शुक्रवार को दोहराता है

फिर यह एक और अधिक जटिल पैटर्न है।


मैं इस गाइड का पालन करता हूं: https://github.com/bmoeskau/Extensible/blob/master/recurrence-overview.md

यह भी सुनिश्चित करें कि आप iCal प्रारूप का उपयोग करें ताकि पहिया को फिर से शुरू न किया जाए और नियम # 0 याद रखें: व्यक्तिगत आवर्ती ईवेंट उदाहरणों को अपने डेटाबेस में पंक्तियों के रूप में संग्रहीत न करें!


सिस्टम टेबल में संग्रहीत MySQL घटनाओं की तरह बहुत अधिक लगता है। आप संरचना को देख सकते हैं और पता लगा सकते हैं कि किन कॉलम की आवश्यकता नहीं है:

   EVENT_CATALOG: NULL
    EVENT_SCHEMA: myschema
      EVENT_NAME: e_store_ts
         DEFINER: [email protected]
      EVENT_BODY: SQL
EVENT_DEFINITION: INSERT INTO myschema.mytable VALUES (UNIX_TIMESTAMP())
      EVENT_TYPE: RECURRING
      EXECUTE_AT: NULL
  INTERVAL_VALUE: 5
  INTERVAL_FIELD: SECOND
        SQL_MODE: NULL
          STARTS: 0000-00-00 00:00:00
            ENDS: 0000-00-00 00:00:00
          STATUS: ENABLED
   ON_COMPLETION: NOT PRESERVE
         CREATED: 2006-02-09 22:36:06
    LAST_ALTERED: 2006-02-09 22:36:06
   LAST_EXECUTED: NULL
   EVENT_COMMENT:

अपाचे क्रॉन नौकरियों के समान तंत्र का उपयोग क्यों न करें? http://en.wikipedia.org/wiki/Cron

कैलेंडर \ शेड्यूलिंग के लिए मैं मानक कैलेंडर रीक्योरेंस घटनाओं को समायोजित करने के लिए "बिट्स" के लिए थोड़ा अलग मानों का उपयोग करता हूं - [सप्ताह के दिन (0 - 7), महीने (1 - 12), महीने का दिन (1 - 31), घंटा (0 - 23), न्यूनतम (0 - 5 9)]

- मैं कुछ [वर्ष (प्रत्येक एन साल दोहराएं), महीने (1 - 12), महीने का दिन (1 - 31), महीने का सप्ताह (1-5), सप्ताह का दिन (0-7) ]

उम्मीद है की यह मदद करेगा।


जबकि वर्तमान में स्वीकृत उत्तर मेरे लिए एक बड़ी मदद थी, मैं कुछ उपयोगी संशोधन साझा करना चाहता था जो प्रश्नों को सरल बनाते हैं और प्रदर्शन को भी बढ़ाते हैं।

"सरल" दोहराना घटनाक्रम

उन कार्यक्रमों को संभालने के लिए जो नियमित अंतराल पर पुनरावृत्ति करते हैं, जैसे कि:

Repeat every other day 

या

Repeat every week on Tuesday 

आपको दो टेबल बनाना चाहिए, इस तरह की events बुलाया जाना चाहिए:

ID    NAME
1     Sample Event
2     Another Event

और events_meta नामक एक टेबल इस तरह है:

ID    event_id      repeat_start       repeat_interval
1     1             1369008000         604800            -- Repeats every Monday after May 20th 2013
1     1             1369008000         604800            -- Also repeats every Friday after May 20th 2013

repeat_start बिना किसी समय के एक यूनिक्स टाइमस्टैम्प दिनांक होने के साथ (1369008000 20 मई 2013 से मेल खाता है), और अंतराल के बीच सेकंड में एक राशि repeat_interval (604800 7 दिन है)।

कैलेंडर में प्रत्येक दिन लूपिंग करके आप इस सरल क्वेरी का उपयोग करके दोहराने वाली घटनाएं प्राप्त कर सकते हैं:

SELECT EV.*
FROM `events` EV
RIGHT JOIN `events_meta` EM1 ON EM1.`event_id` = EV.`id`
WHERE  (( 1299736800 - repeat_start) % repeat_interval = 0 )

बस अपने कैलेंडर में प्रत्येक तारीख के लिए यूनिक्स-टाइमस्टैम्प (12 99736800) में प्रतिस्थापित करें।

मॉड्यूलो (% साइन) के उपयोग पर ध्यान दें। यह प्रतीक नियमित विभाजन की तरह है, लेकिन मात्रा के बजाए 'शेष' 'देता है, और जब भी वर्तमान दिनांक दोहराना_स्टार्ट से repeat_interval का सटीक एकाधिक होता है।

प्रदर्शन तुलना

यह पहले सुझाए गए "मेटा_की"-आधारित उत्तर की तुलना में काफी तेज़ है, जो निम्नानुसार था:

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 ( 1299132000 - EM1.`meta_value` )
            WHEN 0
              THEN 1
            ELSE ( 1299132000 - EM1.`meta_value` )
          END
        ) / EM2.`meta_value`
    ) = 1

यदि आप इस क्वेरी को EXPLAIN चलाते हैं, तो आप ध्यान दें कि इसमें शामिल बफर का उपयोग आवश्यक है:

+----+-------------+-------+--------+---------------+---------+---------+------------------+------+--------------------------------+
| id | select_type | table | type   | possible_keys | key     | key_len | ref              | rows | Extra                          |
+----+-------------+-------+--------+---------------+---------+---------+------------------+------+--------------------------------+
|  1 | SIMPLE      | EM1   | ALL    | NULL          | NULL    | NULL    | NULL             |    2 | Using where                    |
|  1 | SIMPLE      | EV    | eq_ref | PRIMARY       | PRIMARY | 4       | bcs.EM1.event_id |    1 |                                |
|  1 | SIMPLE      | EM2   | ALL    | NULL          | NULL    | NULL    | NULL             |    2 | Using where; Using join buffer |
+----+-------------+-------+--------+---------------+---------+---------+------------------+------+--------------------------------+

ऊपर शामिल 1 के साथ समाधान के लिए ऐसा कोई बफर की आवश्यकता नहीं है।

"परिसर" पैटर्न

आप इन प्रकार के दोहराव नियमों का समर्थन करने के लिए अधिक जटिल प्रकारों के लिए समर्थन जोड़ सकते हैं:

Event A repeats every month on the 3rd of the month starting on March 3, 2011

या

Event A repeats second Friday of the month starting on March 11, 2011

आपकी इवेंट टेबल बिल्कुल वही दिख सकती है:

ID    NAME
1     Sample Event
2     Another Event

फिर इन जटिल नियमों के लिए समर्थन जोड़ने के लिए events_meta कॉलम जोड़ें:

ID    event_id      repeat_start       repeat_interval    repeat_year    repeat_month    repeat_day    repeat_week    repeat_weekday
1     1             1369008000         604800             NULL           NULL            NULL          NULL           NULL             -- Repeats every Monday after May 20, 2013
1     1             1368144000         604800             NULL           NULL            NULL          NULL           NULL             -- Repeats every Friday after May 10, 2013
2     2             1369008000         NULL               2013           *               *             2              5                -- Repeats on Friday of the 2nd week in every month    

ध्यान दें कि आपको बस एक repeat_interval या repeat_interval एक सेट, repeat_month , repeat_day , repeat_week , और repeat_weekday डेटा निर्दिष्ट करने की आवश्यकता है।

यह दोनों प्रकार के चयन को एक साथ बहुत सरल बनाता है। बस प्रत्येक दिन के माध्यम से लूप करें और सही मानों को भरें, (770563200 7 जून 2013 के लिए, और फिर वर्ष, महीना, दिन, सप्ताह संख्या और सप्ताहांत निम्नानुसार है):

SELECT EV.*
FROM `events` EV
RIGHT JOIN `events_meta` EM1 ON EM1.`event_id` = EV.`id`
WHERE  (( 1370563200 - repeat_start) % repeat_interval = 0 )
  OR ( 
    (repeat_year = 2013 OR repeat_year = '*' )
    AND
    (repeat_month = 6 OR repeat_month = '*' )
    AND
    (repeat_day = 7 OR repeat_day = '*' )
    AND
    (repeat_week = 2 OR repeat_week = '*' )
    AND
    (repeat_weekday = 5 OR repeat_weekday = '*' )
    AND repeat_start <= 1370563200
  )

यह उन सभी घटनाओं को लौटाता है जो दूसरे सप्ताह के शुक्रवार को दोहराते हैं, साथ ही प्रत्येक शुक्रवार को दोहराए जाने वाले किसी भी कार्यक्रम को लौटाते हैं, इसलिए यह ईवेंट आईडी 1 और 2 दोनों देता है:

ID    NAME
1     Sample Event
2     Another Event

* उपर्युक्त एसक्यूएल में सिडेनोटे ने PHP दिनांक की डिफ़ॉल्ट सप्ताहांत इंडेक्स का उपयोग किया, इसलिए शुक्रवार के लिए "5"

उम्मीद है कि इससे दूसरों को मूल उत्तर में मदद मिलेगी!


@ रॉग कोडर

यह भी खूब रही!

अंत में अपना कोड सरल बनाने के लिए आप बस मॉड्यूलो ऑपरेशन (एमओडी या% mysql में) का उपयोग कर सकते हैं:

के बजाय:

AND (
    ( CASE ( 1299132000 - EM1.`meta_value` )
        WHEN 0
          THEN 1
        ELSE ( 1299132000 - EM1.`meta_value` )
      END
    ) / EM2.`meta_value`
) = 1

कर:

$current_timestamp = 1299132000 ;

AND ( ('$current_timestamp' - EM1.`meta_value` ) MOD EM2.`meta_value`) = 1")

इसे आगे बढ़ाने के लिए, कोई ऐसी घटनाओं को शामिल कर सकता है जो हमेशा के लिए पुनरावृत्ति नहीं करते हैं।

अंतिम "repeat_interval_1" की तारीख को दर्शाने के लिए "repeat_interval_1_end" जैसा कुछ जोड़ा जा सकता है। हालांकि, यह क्वेरी अधिक जटिल बनाती है और मैं वास्तव में यह नहीं समझ सकता कि यह कैसे करें ...

शायद कोई मदद कर सकता है!


आप add विधि का उपयोग कर सकते हैं और इसे ऋणात्मक संख्या पास कर सकते हैं। हालांकि, आप एक सरल विधि भी लिख सकते हैं जो निम्नानुसार Calendar वर्ग का उपयोग नहीं करती है

public static void addDays(Date d, int days)
{
    d.setTime( d.getTime() + (long)days*1000*60*60*24 );
}

यह तिथि का टाइमस्टैम्प मान (युग के बाद मिलीसेकंड) प्राप्त करता है और मिलीसेकंड की उचित संख्या जोड़ता है। आप घटाव करने के लिए दिन पैरामीटर के लिए एक ऋणात्मक पूर्णांक पारित कर सकते हैं। यह "उचित" कैलेंडर समाधान से सरल होगा:

public static void addDays(Date d, int days)
{
    Calendar c = Calendar.getInstance();
    c.setTime(d);
    c.add(Calendar.DATE, days);
    d.setTime( c.getTime().getTime() );
}

ध्यान दें कि इन दोनों समाधानों में पूरी तरह से नई Date लौटने के बजाय पैरामीटर के रूप में पारित Date वस्तु को बदल दिया गया है। वांछित अगर इसे किसी अन्य तरीके से करने के लिए आसानी से बदल दिया जा सकता है।





database-design calendar