2012-04-02 17 views
7

के साथ कस्टम CGridView के लिए क्वेरी मैनिपुलेशन इसलिए, मैंने अपने संगठन की ज़रूरतों के अनुरूप एक उन्नत खोज सुविधा शामिल करने के लिए CGridView बढ़ाया है।वाईआई - उन्नत खोज

  • फ़िल्टर - आप तालिका में/छिपाने कॉलम दिखा देता है, और तुम भी प्रत्येक आइटम के बाईं ओर थोड़ा खींचें आइकन खींचकर स्तंभों को पुन: व्यवस्थित कर सकते हैं।
  • क्रमबद्ध करें - एकाधिक कॉलम के चयन की अनुमति देता है, आरोही या उतरना निर्दिष्ट करें।
  • खोज - अपना कॉलम चुनें और खोज पैरामीटर डालें। चयनित कॉलम के डेटा प्रकार के अनुरूप ऑपरेटर।

Advanced Search Screenshot

संस्करण 1 काम करता है, हालांकि धीरे। असल में, मेरे पास CGridView की आंतरिक कार्यप्रणाली में मेरे हाथ थे, जहां मैं DataProvider से परिणाम छीनता हूं और तालिका सामग्री को प्रस्तुत करने से पहले PHP में खोज और सॉर्टिंग करता हूं।

अब संस्करण 2 लिख रहा है, जहां मेरा उद्देश्य चालाक CDbCriteria निर्माण पर ध्यान केंद्रित करना है, जिससे MySQL भारी उठाने की अनुमति देता है ताकि यह तेज़ी से चल सके। एकल डेटाबेस तालिका से निपटने के दौरान कार्यान्वयन छोटा होता है। कठिनाई तब होती है जब मैं 2 या अधिक तालिकाओं से निपट रहा हूं ... उदाहरण के लिए, यदि उपयोगकर्ता STAT संबंध वाले क्षेत्र पर खोज करना चाहता है, तो मुझे उस प्रश्न के संबंध में मेरी क्वेरी में मौजूद होना चाहिए ताकि मैं तुलना शामिल कर सकूं ।

यहां सवाल है। मैं कैसे आश्वस्त करूं कि वाईआई में मेरी क्वेरी में सभी with संबंध शामिल हैं ताकि मैं तुलना शामिल कर सकूं? मैं अपने सभी संबंधों with मॉडल search समारोह में अपने मापदंड शामिल की है और मैं सच करने के लिए CDbCriteria के together सेट की कोशिश की है ...

public function search() { 
    $criteria=new CDbCriteria; 
    $criteria->compare('id', $this->id); 
    $criteria->compare(... 
    ... 
    $criteria->with = array('relation0','relation1','relation3'); 
    $criteria->together = true; 

    return new CActiveDataProvider(
     get_class($this), array(
      'criteria'=>$criteria, 
      'pagination' => array('pageSize' => 50) 
));} 

तब मैं DataProvider और add a few conditions से मापदंड छीन कर देंगे, के लिए उदाहरण के लिए, दिनांक> 1234567890. की तलाश में लेकिन मैं अभी भी इस तरह त्रुटियों मिलता है ...

CDbCommand failed to execute the SQL statement: 
SQLSTATE[42S22]: Column not found: 1054 Unknown column 't.relation3' in 'where clause'. 
The SQL statement executed was: 
SELECT COUNT(DISTINCT `t`.`id`) FROM `table` `t` 
LEFT OUTER JOIN `relation_table` `relation0` ON (`t`.`id`=`relation0`.`id`) 
LEFT OUTER JOIN `relation_table` `relation1` ON (`t`.`id`=`relation1`.`id`) 
WHERE (`t`.`relation3` > 1234567890) 

कहाँ relation0 और relation1BELONGS_TO संबंधों हैं, लेकिन किसी STAT संबंध, यहाँ depicte relation3 के रूप में, गायब हैं। इसके अलावा, प्रश्न SELECT COUNT(DISTINCT 't'.'id') क्यों है?

संपादित करें @ डीकोडर यहां विशिष्ट संबंध है जो मैं अभी काम कर रहा हूं। मुख्य तालिका कॉल है, जिसमें HAS_MANY कॉलसेगमेंट्स के संबंध में है, जो समय रखता है। तो कॉल के startTime सभी संबंधित कॉलेजमेंट का न्यूनतम स्टार्ट_टाइम है। और startTime मेरी अनामित क्वेरी त्रुटि में hypothetical relation3 है।

'startTime' => array(self::STAT, 'CallSegments', 'call_id', 
      'select' => 'min(`start_time`)'), 

संपादित अन्य लोगों ने मुझे CDbCriteria's together property को भेज दिया है, लेकिन जैसा कि आप ऊपर देख सकते हैं, मैं वर्तमान में कोई लाभ नहीं हुआ है कि कोशिश कर रहा हूँ।Yii और github टिकट:

संपादित मुद्दा सूचित किया गया है हो सकता है की तरह लग रहा है।

+1

क्या आप अधिक संबंधित कोड दिखा सकते हैं, विशेष रूप से मॉडल के संबंध घोषणाएं? स्टेट संबंध आमतौर पर अलग-अलग प्रश्नों के रूप में निष्पादित होते हैं। – DCoder

+0

ठीक है @ डीकोडर, मैंने उस संबंध को जोड़ा है जिसे मैं अभी काम कर रहा हूं। क्या आपको और चाहिए? क्वेरी में स्टेट संबंध जोड़ने का कोई तरीका? मैंने सोचा कि सीडीबीक्रिटरिया एक साथ क्या था, लेकिन स्पष्ट रूप से नहीं। –

+0

यह अभी भी मुझे स्पष्ट नहीं है कि आपका अनामित संबंध 0, relation1 और relation3 क्या हैं, लेकिन मुझे लगता है कि आपको एक temp तालिका में call_id और min (start_time) चुनने और STAT पर भरोसा करने के बजाय उस तालिका में शामिल होने की आवश्यकता होगी। यदि आपका डेटाबेस इंजन गणना वाले कॉलम का समर्थन करता है, तो यह एक सभ्य विकल्प हो सकता है। – DCoder

उत्तर

2

एसक्यूएल को मानदंडों से छीनना और अपने आप से इसका उपयोग करना अच्छा नहीं है।

आप "के साथ" संपत्ति का उपयोग कर रहे हैं तो आप आसानी से की तरह तुलना इस्तेमाल कर सकते हैं:

$criteria->compare("`relation1`.`id`", $yourVarHere); 

इसके अलावा Yii अच्छी तरह से समूह के साथ व्यवहार नहीं करता।

मेरे STAT संबंधों के साथ दृष्टिकोण Yii का चयन, बाद में एक सबक्वेरी उपयोग कर रहा है होने से:

$criteria->select = array("`t`.*", "(SELECT COUNT(*) FROM `relation3` WHERE `id` = `t`.id_relation3) AS `rel3`"); 
$criteria->having = "`rel3` > " . $yourValue; 

उपरोक्त विधि gridview पृष्ठांकन में एक बग क्योंकि गिनती एक अलग प्रश्न पर किया जाता है बनाता है। का संभावित हल संपत्ति "के साथ" ड्रॉप और लिखना "में शामिल होने" की तरह संपत्ति में अपने आप से जुड़ जाता है करने के लिए किया जाएगा:

$criteria->join = "LEFT OUTER JOIN `relation_table` `relation0` ON (`t`.`id`=`relation0`.`id`) 
LEFT OUTER JOIN `relation_table` `relation1` ON (`t`.`id`=`relation1`.`id`) 
LEFT OUTER JOIN `relation_table` `relation3` ON (`t`.`id`=`relation3`.`id`)"; 
0

बग आप एक के रूप में स्टेट संबंध इस्तेमाल कर सकते हैं काम कर रहे प्राप्त करने के लिए थोड़ा मुश्किल है सरल HAS_ONE के साथ:

'select'=>'count(relation3.id)', 
'joinType'=>'left join', 
'group'=>'relation3.id', 
'on'=>'t.id = relation3.id', 
'together'=>true 

अन्य सभी के साथ गिनती मूल्य प्राप्त करने के लिए?

यह सुनिश्चित नहीं है कि यह आपके मामले के लिए कितना अच्छा काम करेगा लेकिन समय-समय पर मेरे लिए यह सहायक रहा है।