Mysql
 sql >> डेटाबेस >  >> RDS >> Mysql

ईवेंट के साथ सभी ईवेंट चुनें-> शेड्यूल-> केकपीएचपी में प्रारंभ और समाप्ति तिथियों के बीच की तिथि

इस तरह की स्थिति में, मैं केक के संघों, या कंटेनर का उपयोग नहीं करता, और खुद को जोड़ने का काम करता हूं:

$events = $this->Event->find('all', array(
    'joins'=>array(
        array(
            'table' => $this->Schedule->table, 
            'alias' => 'Schedule', 
            'type' => 'INNER', 
            'foreignKey' => false,
            'conditions'=> array(
                'Schedule.event_id = Event.id',
            ),
        ),
        array(
            'table' => $this->Date->table, 
            'alias' => 'Date', 
            'type' => 'INNER', 
            'foreignKey' => false,
            'conditions'=> array(
                'Date.schedule_id = Schedule.id',
            ),
        ),
    ),
    'conditions'=>array(
        'Date.start >=' => $start_date,
        'Date.start <=' => $end_date,
    ),
    'order'=>'Event.created DESC',
    'limit'=>5
));

यह थोड़ा छोटा है, लेकिन मुझे सटीक क्वेरी का परिणाम चाहिए।

अपडेट करें

आइए आपके कोड को भागों में तोड़ें और देखें कि हम इसे कहां सुधार सकते हैं। पहला भाग find . की तैयारी है . मैंने आपके कोड को छोटा करने का प्रयास करते हुए फिर से लिखा है, और मैं यही लेकर आया हूं:

// Default options go here
$defaultOpts = array(
    'start' => date('Y-m-d') . ' 00:00:00',
    'end' => date('Y-m-d') . ' 23:59:59',
    'limit' => 10
)

// Use default options if nothing is passed, otherwise merge passed options with defaults
$opts = is_array($opts) ? array_merge($defaultOpts, $opts) : $defaultOpts;

// Initialize array to hold query conditions
$conditions = array();

//date conditions
$conditions[] = array(
    "Date.start >=" => $qOpts['start'],
    "Date.start <=" => $qOpts['end'],
));

//cities conditions
if(isset($opts['cities']) && is_array($opts['cities'])) {
    $conditions['OR'] = array();
    $conditions['OR'][] = array('Venue.city_id'=>$opts['cities']);
    $conditions['OR'][] = array('Restaurant.city_id'=>$opts['cities']);
}

//event types conditions
//$opts['event_types'] = array('1');
if(isset($opts['event_types']) && is_array($opts['event_types'])) {
    $conditions[] = 'EventTypesEvents.event_type_id' => $opts['event_types']
}

//event sub types conditions
if(isset($opts['event_sub_types']) && is_array($opts['event_sub_types'])) {
    $conditions[] = 'EventSubTypesEvents.event_sub_type_id' => $opts['event_sub_types']
}

//event sub sub types conditions
if(isset($opts['event_sub_types']) && is_array($opts['event_sub_sub_types'])) {
    $conditions[] = 'EventSubSubTypesEvents.event_sub_sub_type_id' => $opts['event_sub_sub_types']
}

ध्यान दें कि मैंने अधिकांश ओआरएस हटा दिए हैं। ऐसा इसलिए है क्योंकि आप किसी सरणी को conditions . में मान के रूप में पास कर सकते हैं , और केक इसे एक IN(...) . बना देगा SQL क्वेरी में कथन। उदाहरण के लिए:'Model.field' => array(1,2,3) उत्पन्न करता है 'Model.field IN (1,2,3)' . यह ओआरएस की तरह ही काम करता है, लेकिन इसके लिए कम कोड की आवश्यकता होती है। तो ऊपर दिया गया कोड ब्लॉक ठीक वैसा ही करता है जैसा आपका कोड कर रहा था, लेकिन यह छोटा है।

अब जटिल भाग आता है, find स्वयं।

आमतौर पर मैं कंटेनेबल के बिना, और 'recursive'=>false के साथ, जबरन जॉइन करने की अनुशंसा करता हूं . मेरा मानना ​​है कि यह आमतौर पर जटिल खोजों से निपटने का सबसे अच्छा तरीका है। एसोसिएशन और कंटेनर के साथ, केक डेटाबेस के खिलाफ कई SQL क्वेरी चलाता है (प्रति मॉडल/टेबल एक क्वेरी), जो अक्षम हो जाता है। साथ ही, कंटेनर हमेशा अपेक्षित परिणाम नहीं लौटाता है (जैसा कि आपने कोशिश करते समय देखा था)।

लेकिन चूंकि आपके मामले में चार . हैं जटिल संघ शामिल हैं, शायद एक मिश्रित दृष्टिकोण आदर्श समाधान होगा - अन्यथा, डुप्लिकेट डेटा को साफ करना बहुत जटिल होगा। (चार जटिल संघ हैं:ईवेंट में कई तिथियां होती हैं [ईवेंट के माध्यम से कई शेड्यूल होते हैं, शेड्यूल में कई तिथियां होती हैं], इवेंट एचएबीटीएम इवेंट टाइप, इवेंट एचएबीटीएम इवेंटसब टाइप, इवेंट एचएबीटीएम इवेंट सबसब टाइप)। इसलिए, हम बहुत अधिक डुप्लिकेट से बचते हुए, केक को EventType, EventSubType और EventSubSubType के डेटा पुनर्प्राप्ति को संभालने दे सकते हैं।

तो मेरा सुझाव है:सभी आवश्यक फ़िल्टरिंग के लिए जॉइन का उपयोग करें, लेकिन फ़ील्ड में दिनांक और [उप [उप]] प्रकार शामिल न करें। आपके पास मॉडल संघों के कारण, केक डेटा के उन बिट्स को लाने के लिए डीबी के खिलाफ स्वचालित रूप से अतिरिक्त प्रश्न चलाएगा। किसी कंटेनर की आवश्यकता नहीं है।

कोड:

// We already fetch the data from these 2 models through
// joins + fields, so we can unbind them for the next find,
// avoiding extra unnecessary queries. 
$this->unbindModel(array('belongsTo'=>array('Restaurant', 'Venue'));

$data = $this->find('all', array(
    // The other fields required will be added by Cake later
    'fields' => "
        Event.*, 
        Restaurant.id, Restaurant.name, Restaurant.slug, Restaurant.address, Restaurant.GPS_Lon, Restaurant.GPS_Lat, Restaurant.city_id,
        Venue.id, Venue.name, Venue.slug, Venue.address, Venue.GPS_Lon, Venue.GPS_Lat, Venue.city_id,
        City.id, City.name, City.url_name
    ",  
    'joins' => array(
        array(
            'table' => $this->Schedule->table,
            'alias' => 'Schedule',
            'type' => 'INNER',
            'foreignKey' => false,
            'conditions' => 'Schedule.event_id = Event.id',
        ),
        array(
            'table' => $this->Schedule->Date->table,
            'alias' => 'Date',
            'type' => 'INNER',
            'foreignKey' => false,
            'conditions' => 'Date.schedule_id = Schedule.id',
        ),
        array(
            'table' => $this->EventTypesEvent->table,
            'alias' => 'EventTypesEvents',
            'type' => 'INNER',
            'foreignKey' => false,
            'conditions' => 'EventTypesEvents.event_id = Event.id',
        ),
        array(
            'table' => $this->EventSubSubTypesEvent->table,
            'alias' => 'EventSubSubTypesEvents',
            'type' => 'INNER',
            'foreignKey' => false,
            'conditions' => 'EventSubSubTypesEvents.event_id = Event.id',
        ),
        array(
            'table' => $this->Restaurant->table,
            'alias' => 'Restaurant',
            'type' => 'LEFT',
            'foreignKey' => false,
            'conditions' => 'Event.restaurant_id = Restaurant.id',
        ),
        array(
            'table' => $this->City->table,
            'alias' => 'RestaurantCity',
            'type' => 'LEFT',
            'foreignKey' => false,
            'conditions' => 'Restaurant.city_id = city.id',
        ),
        array(
            'table' => $this->Venue->table,
            'alias' => 'Venue',
            'type' => 'LEFT',
            'foreignKey' => false,
            'conditions' => 'Event.venue_id = Venue.id',
        ),
        array(
            'table' => $this->City->table,
            'alias' => 'VenueCity',
            'type' => 'LEFT',
            'foreignKey' => false,
            'conditions' => 'Venue.city_id = city.id',
        ),
    ),
    'conditions' => $conditions,
    'limit' => $opts['limit'],
    'recursive' => 2
));

हमने हटा दिया contains , और कुछ अतिरिक्त प्रश्नों के कारण केक चल रहा था। अधिकांश जॉइन INNER . प्रकार के होते हैं . इसका मतलब यह है कि शामिल होने में शामिल दोनों तालिकाओं पर कम से कम एक रिकॉर्ड मौजूद होना चाहिए, या आप कम परिणाम प्राप्त करेंगे जो आप उम्मीद करेंगे। मैं मान रहा हूँ कि प्रत्येक कार्यक्रम एक रेस्तरां में होता है या एक स्थान, लेकिन दोनों नहीं, इसलिए मैंने LEFT . का उपयोग किया उन तालिकाओं (और शहरों) के लिए। यदि जॉइन में प्रयुक्त कुछ फ़ील्ड वैकल्पिक हैं, तो आपको LEFT . का उपयोग करना चाहिए INNER . के बजाय संबंधित जॉइन पर।

अगर हमने 'recursive'=>false . का इस्तेमाल किया है यहां, हमें अभी भी सही घटनाएं मिलेंगी, और कोई डेटा पुनरावृत्ति नहीं होगी, लेकिन तिथियां और [उप [उप]] प्रकार गायब होंगे। रिकर्सन के 2 स्तरों के साथ, केक स्वचालित रूप से लौटाए गए ईवेंट के माध्यम से लूप करेगा, और प्रत्येक ईवेंट के लिए यह संबंधित मॉडल डेटा लाने के लिए आवश्यक क्वेरी चलाएगा।

यह लगभग वही है जो आप कर रहे थे, लेकिन बिना कंटेनर के, और कुछ अतिरिक्त बदलावों के साथ। मुझे पता है कि यह अभी भी एक लंबा, बदसूरत और उबाऊ कोड है, लेकिन आखिरकार इसमें 13 डेटाबेस टेबल शामिल हैं...

यह सब परीक्षण न किया गया कोड है, लेकिन मेरा मानना ​​है कि यह काम करना चाहिए।



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PHP और jQuery के साथ लाइव चैट करें। जानकारी कहाँ स्टोर करें? MySQL या फ़ाइल?

  2. MySQL में चल रहे कुल की गणना करें

  3. MySQL 5.0 अनुक्रमणिका - अद्वितीय बनाम गैर अद्वितीय

  4. टर्मिनल में सबसे अच्छा प्रदर्शन कैसे करें एक MySQL चयन बहुत सारे फ़ील्ड लौटा रहा है?

  5. MySQL में एक-से-अनेक संबंध - कैसे मॉडल बनाने के लिए?